Reputation: 7514
I am trying to log all method calls for an object. By overriding __getattribute__
, I can intercept these calls and print them. My actual object has dozens of methods. To simplify, let's look at a simpler object. Something like this:
class Classy:
def do_it(self):
print('We did it!')
def __getattribute__(self, attr):
print(f'Calling {attr}')
return Classy.__getattribute__(self, attr)
c = Classy()
c.do_it()
This code throws:
RecursionError: maximum recursion depth exceeded while calling a Python object
How can __getattribute__
look up a method in the child class while bypassing a call to itself?
EDIT: Interestingly, the call to __init__()
bypassed __getattribute__
. Instead, the error was triggered by the call to do_it()
. That might be a clue.
EDIT2: This is a related question. But after studying the answers there, it still wasn't clear (to me at least) that calls to the parent's __getattribute__
method would in turn get the child class method.
Upvotes: 0
Views: 591
Reputation: 5152
You need to access the underlying object
instead of your class:
class Classy:
def do_it(self):
print('We did it!')
def __getattribute__(self, attr):
print(f'Calling {attr}')
return object.__getattribute__(self, attr)
Upvotes: 1
Reputation: 531185
You need to call the parent's __getattribute__
method, which is what would have been called had you not defined Classy.__getattribute__
.
class Classy:
def do_it(self):
print('We did it!')
def __getattribute__(self, attr):
print(f'Calling {attr}')
return super().__getattribute__(attr)
Upvotes: 2