Get rid of recursive call __getattr__

Peter Otten __peter__ at web.de
Wed Dec 14 09:29:43 EST 2005


Pelmen wrote:

> >>> class Test:
>           def __getattr__(self, attr):
>             print attr
> 
>           def foo(x):
>             print x
> 
> >>> t = Test()
> >>> print t
> __str__
> 
> Traceback (most recent call last):
>   File "<pyshell#23>", line 1, in -toplevel-
>     print t
> TypeError: 'NoneType' object is not callable
> 
> what i have to do? define __str__ explicitly?

By seemingly not returning anything your __getattr__() method actually
returns None. Instead you should raise an AttributeError when your
__getattr__() encounters the name of an attribute it doesn't handle.
Let's assume Test.__getattr__() should implement an attribute 'alpha' and
nothing else:

>>> class Test:
...     def __getattr__(self, name):
...             print "looking up", name
...             if name == "alpha":
...                     return 42
...             print "lookup failed for", name
...             raise AttributeError
...
>>> print Test()
looking up __str__
lookup failed for __str__
looking up __repr__
lookup failed for __repr__
<__main__.Test instance at 0x4029248c>

When the lookup fails in the instance it is deferred to the class.
By the way, new-style classes handle __special__ methods a bit differently
-- try deriving Test from object 

class Test(object):
   # same as above

to see the difference.

Peter




More information about the Python-list mailing list