There are a couple of obvious problems with your code:
class A(object):
def __getattr__(self, item): # 1
print item
return self.item # 2
def x(self): # 1 again
print 4
__getattr__
will only be invoked if item
cannot be found the normal way. For item == 'x'
, therefore, it is never invoked.
- Which is probably just as well, since
self.item
looks for the attribute item
, not the attribute corresponding to whatever is assigned to item
. This doesn't exist, so would invoke __getattr__
. If you try A().y()
you'll get RuntimeError: maximum recursion depth exceeded while calling a Python object
.
Instead, I think you want to use __getattribute__
, which is always invoked. You need to be careful not to get the same runtime error, though; here I avoid it by calling the superclass implementation of __getattribute__
, the naïve way of calling getattr(self, item)
would fail:
class A(object):
def __getattribute__(self, item):
print item
return super(A, self).__getattribute__(item)
def x(self):
print 4
Which gives:
>>> A().x()
x
4
>>> A().y()
y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __getattribute__
AttributeError: 'A' object has no attribute 'y'
Note that both __getattr__
and __getattribute__
apply equally to attributes and methods (which are, more or less, just callable attributes).