In Python's documentation, on the __getattr__
function it says:
Note that if the attribute is found through the normal mechanism, __getattr__() is not called. (This is an intentional asymmetry between __getattr__() and __setattr__().) This is done both for efficiency reasons and because otherwise __getattr__() would have no way to access other attributes of the instance.
I have a problem understanding the last statement:
would have no way to access other attributes of the instance
How exactly would it have no way to access other attributes? (I guess it has something to do with infinite recursion but aren't there other ways to acces instance attributes, like from self.__dict__
directy?)
You'd have an infinite recursion if you tried to use self.__dict__[key]
as self.__dict__
would call __getattr__
, etc, etc. Of course, you can break out of this cycle if you use object.__getattr__(self,key)
, but that only works for new style classes. There is no general mechanism that you could use with old style classes.
Note that you don't have this problem with __setattr__
because in that case, you can use self.__dict__
directly (Hence the asymmetry).
The __getattribute__()
magic method is the pair with __setattr__()
, but with great power comes great responsibility. __getattr__()
is provided so that you don't have to assume the great responsibility part. As @mgilson points out in the comments, if __getattr__()
worked as __getattribute__()
does, you would be unable to access any attributes off the instance from within __getattr__()
, because even to look at self.__dict__
you need to use the attribute lookup machinery.
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