問題描述
我為一種 android lock 編寫了一個代碼,每當(dāng)我嘗試使用 id 獲取特定的 ClickableImage 時,它??都會引發(fā)以下錯誤:
I wrote a code for a kind of android lock thing, whenever I try to get an specific ClickableImage using the id it raises the following error:
AttributeError: 'super' object has no attribute '__getattr__'
我花了幾個小時試圖尋找這個問題的解決方案,我查看了其他有同樣問題的人,人們告訴他們更改構(gòu)建器的站點,因為需要首先調(diào)用它來獲取 id屬性或類似的東西,但每次我移動構(gòu)建器時,它都會引發(fā)錯誤類未定義".有什么線索嗎?
I've spent hours trying to look for a solution for this problem, I looked other people with the same issue, and people told them to change the site of the builder, because it needed to be called first to get the ids attribute or something like that, but everytime I move the builder, it raises the error "class not defined". Any clues?
這是我的代碼:
from kivy.app import App
from kivy.config import Config
from kivy.lang import Builder
from kivy.graphics import Line
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import ButtonBehavior
#Variables
cords = ()
bld = Builder.load_file('conf.kv')
class Manager(ScreenManager): pass
class Principal(Screen): pass
class ClickableImage(ButtonBehavior, Image):
def on_press(self):
self.source = 'button_press.png'
def on_release(self):
self.source = 'button.png'
self.ids.uno.source = 'button_press.png'
class canva(Widget):
def on_touch_down(self, touch):
global cords
with self.canvas:
touch.ud['line'] = Line(points=(touch.x, touch.y), width=1.5)
cords = (touch.x, touch.y)
def on_touch_move(self,touch):
global cords
touch.ud['line'].points = cords + (touch.x, touch.y)
def on_touch_up(self,touch):
self.canvas.clear()
class Api(App):
def build(self):
return bld
if __name__ == '__main__':
Api().run()
這是我的 .kv 文件:
and here is my .kv file:
# conf to file: test.py
<Manager>:
Principal:
<Principal>:
GridLayout:
size_hint_x: 0.5
size_hint_y: 0.6
width: self.minimum_width
cols: 3
ClickableImage:
id: 'uno'
size: 10,10
source: 'button.png'
allow_strech: True
ClickableImage:
id: 'dos'
size: 30,30
source: 'button.png'
allow_strech: True
canva:
推薦答案
讓我們看看輸出:
'super' object has no attribute '__getattr__'
在kv語言中,id
是用特殊方式設(shè)置的(現(xiàn)在到1.9.2),它的值不是字符串,因為它不是一個隨便的變量.您無法使用 <widget>.id
訪問它.
In kv language id
is set in a special way(up to 1.9.2 now), its value is not a string, because it's not a casual variable. You can't access it with <widget>.id
.
我會說它類似于 canvas
,它不是一個小部件,但它可能看起來像那樣(這就是我對你的代碼感到困惑的原因:P).您已經(jīng)注意到 something: <some object>
就像 Python 的 something = <object>
并且(至少我認為)這就是 id
的值不是字符串(這對某些人來說很奇怪).如果 id
是一個字符串,則可能需要進行檢查以以某種方式將其排除在臨時分配值之外.也許是因為性能或只是簡單.
I'd say it's similar to canvas
, which is not a widget, yet it may look like that(which is why I was confused by your code :P). You've already noticed something: <some object>
is like Python's something = <object>
and that's (at least what I think) is the whole point of id
's value not being a string(which to some is odd). If id
was a string, there'd probably be needed a check to exclude it somehow from casual assigning values. Maybe it's because of performance or just simplicity.
因此,假設(shè) id
是未來關(guān)鍵字的關(guān)鍵字.其實是這樣,因為分配給id
的字符會變成一個字符串key,其值為從WeakProxy得到的object,指向WeakProxy指向的object.或者說得更好:
Therefore let's say id
is a keyword for a future keyword. In fact, it is, because the characters assigned to id
will become a string key with a value of object got from WeakProxy, to the object WeakProxy points to. Or better said:
id: value
變成
<some_root_widget>.ids[str(value)] = weakref.proxy(value)
value
變成 object(print(self)
會返回什么)
where value
becomes an object(what print(self)
would return)
我懷疑(不確定)如果你使用字符串作為 id
的值,你最終會得到 weakref/WeakProxy 指向一個細繩.我使用 point
這個詞,因為它提醒我指針,不要與 C 指針混淆.
I suspect(not sure) that if you use string as the value for id
, you'll end up with weakref / WeakProxy pointing to a string. I use the word point
as it reminds me pointers, don't get confused with C pointers.
現(xiàn)在如果你再看一下輸出:
Now if you look again at the output:
super
讓您可以訪問您繼承自的類
super
gives you an access to a class you inherit from
print('string id'.__getattr__)
會給你同樣的錯誤,但是 'super'
被替換為實際值,因為很好... 它沒有 __getattr__
print('string id'.__getattr__)
will give you the same error, but 'super'
is substituted with the real value, because well... it doesn't have __getattr__
因此如果你給id
賦值一個string值,你會遇到這種情況:
Therefore if you assign a string value to id
, you'll get into this situation:
<some_root_widget>.ids[str('value')] = weakref.proxy('value') # + little bit of magic
雖然 str('value')
不一定是錯的,但默認情況下你不能為字符串創(chuàng)建 weakref.proxy.我不確定 Kivy 是如何使用 Wea??kProxies 處理這個問題的,但是如果你給 id
分配一個字符串,大致就是這樣.
Although str('value')
isn't necessarily wrong, by default you can't create weakref.proxy for a string. I'm not sure how Kivy handles this with WeakProxies, but if you assign a string to id
, roughly this is what you get.
(如有錯誤請指正)
這篇關(guān)于Python - Kivy:AttributeError:'super'對象在嘗試獲取self.ids時沒有屬性'__getattr__'的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!