Obscure __getattr__ behavior

holger krekel pyth at devel.trillke.net
Thu Feb 6 22:54:31 EST 2003


D. Herzberg wrote:
> Hi,
> 
> while using __getattr__ in one of my programs, I stumbled
> across the somewhat abscure behavior of __getattr__. Take
> the following code:
> 
> class Test:
>     __attributes__= []
>     def __getattr__(self,name):
>         print "__getattr__(",name,")"
>         if name in self.__attributes__:
>             print "Lookup successful"
>             return self.__attributes__[name]
>         raise AttributeError, "%s not found" % (name)
> 
> If you type in 
> 
> >>> t = Test()
> >>> t
> __getattr__( __repr__ )
> <__main__.Test instance at 0x00778FA8>
> >>>
> 
> When you run the code you know for sure that __getattr__ was
> called with `__repr__' as a parameter; and you know for sure
> that the lookup was not successfull -- so, what code is next?

The __repr__ method is looked up on the underlying type object

    >>> type(t).__repr__
    <slot wrapper '__repr__' of 'instance' objects>

and this happens after your __getattr__ raised an attribute
error.  If you enter

    >>> t.__repr__
    __getattr__( __repr__ )
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 8, in __getattr__
    AttributeError: __repr__ not found
    >>>

then you can see your attribute error.  Now the funny
part is that if you define a new style class (derive
from 'object') then 't.__repr__' would return you 
a method wrapper object.  

Who said classes and types were completly unified? :-)

HTH,

    holger






More information about the Python-list mailing list