Python - Kivy: AttributeError: 'super' object has no attribute '__getattr__' when trying to get self.ids

前端 未结 1 2009
终归单人心
终归单人心 2021-01-05 08:32

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:         


        
相关标签:
1条回答
  • 2021-01-05 09:17

    Let's look at the output:

    'super' object has no attribute '__getattr__'
    

    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.

    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.

    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
    

    becomes

    <some_root_widget>.ids[str(value)] = weakref.proxy(value)
    

    where value becomes an object(what print(self) would return)

    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.

    Now if you look again at the output:

    • super gives you an access to a class you inherit from

    • 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__

    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
    

    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.

    (Please correct me if I'm wrong)

    0 讨论(0)
提交回复
热议问题