Bypassing __getattribute__ for attribute access

Steven Bethard steven.bethard at gmail.com
Thu Oct 25 22:26:49 CEST 2007


Adam Donahue wrote:
>>>> class X( object ):
> ...     def c( self ): pass
> ...
>>>> X.c
> <unbound method X.c>
>>>> x = X()
>>>> x.c
> <bound method X.c of <__main__.X object at 0x81b2b4c>>
> 
> If my interpretation is correct, the X.c's __getattribute__ call knows
> the attribute reference is via a class, and thus returns an unbound
> method (though it does convert the value to a method).

No, that's wrong. It's not the __getattribute__ of "X.c", it's the 
__getattribute__ of "X" itself::

     >>> type.__getattribute__(X, 'c')
     <unbound method X.c>
     >>> X.c.__getattribute__('c')
     Traceback (most recent call last):
       File "<interactive input>", line 1, in <module>
     AttributeError: 'function' object has no attribute 'c'

In the former case, we use the type's __getattribute__, and we get the 
unbound method as expected.  In the latter case, we ask the unbound 
method object for an attribute which it doesn't have

Basically, classes define a __getattribute__ that looks something like::

     def __getattribute__(self, name):
         value = object.__getattribute__(self, name)
         if hasattr(value , '__get__'):
            return value .__get__(None, self)
         return value

For more information, read:

     http://users.rcn.com/python/download/Descriptor.htm

STeVe



More information about the Python-list mailing list