kill129
kill129

Reputation: 100

override __getattr__ for methods and not variables

i want the next code to work

class A(object):
    def __getattr__(self, item):
        print item
        return self.item
    def x(self):
        print 4
a = A()
a.x()

and the output will ber

x
4

i know its not working becuase x is like a static variable and not an instance variable. I saw this __getattr__ for static/class variables in python and it doesn't seem to work in my case how can it be done?

thx

Upvotes: 0

Views: 2638

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122024

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
  1. __getattr__ will only be invoked if item cannot be found the normal way. For item == 'x', therefore, it is never invoked.
  2. 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).

Upvotes: 5

Related Questions