Reputation: 581
In the rare cases that an object's __getattribute__
method must be overridden, a common mistake is to try and return the attribute in question like so:
class WrongWay:
def __getattribute__(self, name):
# Custom functionality goes here
return self.__dict__[name]
This code always yields a RuntimeError
due to a recursive loop, since self.__dict__
is in itself an attribute reference that calls upon the same __getattribute__
method.
According to this answer, the correct solution to this problem is to replace last line with:
...
return super().__getattribute__(self, name) # Defer responsibility to the superclass
This solution works when run through the Python 3 interpreter, but it also seems to violate __getattribute__
's promised functionality. Even if the superclass chain is traversed up to object
, at the end of the line somebody will eventually have to return self.
something, and by definition that attribute reference must first get through the child's __getattribute__
method.
How does Python get around this recursion issue? In object.__getattribute__
, how is anything returned without looping into another request?
Upvotes: 2
Views: 272
Reputation: 280181
at the end of the line somebody will eventually have to return
self.
something, and by definition that attribute reference must first get through the child's__getattribute__()
method.
That's not correct. object.__getattribute__
is not defined as returning self.anything
, and it does not respect descendant class implementations of __getattribute__
. object.__getattribute__
is the default attribute access implementation, and it always performs its job through the default attribute access mechanism.
Similarly, object.__eq__
is not defined as returning self == other_thing
, and it does not respect descendant class implementations of __eq__
. object.__str__
is not defined as returning str(self)
, and it does not respect descendant class implementations of __str__
. object
's methods are the default implementations of those methods, and they always do the default thing.
Upvotes: 2