I had an error in my code (similar to the error below) but the result seems very strange to me. Can someone explain to me how getattr is getting called with the name being "hello"?
class A(object):
def __getattr__(self, name):
print name
assert name != 'hello'
return self.hello
class C(object):
def __init__(self):
class B(A):
@property
def hello(self_):
return self.durp
self.b = B()
c = C()
print c.b.bang
The output of this is:
bang
hello
Traceback (most recent call last):
File "test.py", line 17, in <module>
print c.b.bang
File "test.py", line 5, in __getattr__
return self.hello
File "test.py", line 4, in __getattr__
assert name != 'hello'
AssertionError
shell returned 1
I understand of course that there is no durp property in C (this is the error I speak of). However, I would not expect __getattr__ to be called with hello as the string. I feel like I'm not understanding something fundamental about the way __getattr__ works.
__getattr__ is called when accessing an attribute via "the usual methods" fails. The way Python knows whether "the usual methods" have failed is that an AttributeError is raised. It can't tell, though, whether this AttributeError was raised in trying to get the original attribute you were trying to get, or some other attribute accessed as part of that process. So here's what happens:
c.b.bang__getattr__ is called.__getattr__ tries to get self.hellohello, whose value is a propertyself.hello, Python runs the hello property.hello property tries to access a nonexistent attribute durp. This raises an AttributeErrorself.hello, Python thinks there is no such attribute available via "the usual methods". It therefore calls __getattr__ with "hello" as the argument.This behavior is confusing, but is basically an unavoidable side effect of how attribute lookup in Python works. The only way to know that "normal attribute lookup didn't work" is that an AttributeError was raised. There is a Python bug about this, which apparently people are still working on, but no real solution exists so far.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With