About instance.name look up order

Ian Kelly ian.g.kelly at gmail.com
Thu Dec 29 13:35:49 EST 2011


On Thu, Dec 29, 2011 at 9:07 AM, Prim <ukim86 at gmail.com> wrote:
> class C:
>    def x(self):
>        print 'x method'
>    def __getattr__(self, attr):
>        print 'in __getattr__ method'
>        return attr
> c = C()
> c.x --> print in __getattr__ method, then throw TypeError: 'str'
> object is not callable
> c.x() --> print in __getattr__ method, x method 2 lines
> #Q2: why c.x would get a exception?

I'm not sure exactly what's going on there, but as a general rule you
should use new-style classes, not classic classes, which are
deprecated and have been removed in Python 3.  In Python 2 if you
define a class without any base classes, you get a classic class.  To
define C as a new-style class in Python 2, derive it from object (or
another new-style class):

>>> class C(object):
...     def x(self):
...         print 'x method'
...     def __getattr__(self, attr):
...         print 'in __getattr__ method'
...         return attr
...
>>> c = C()
>>> c.x
<bound method C.x of <__main__.C object at 0x00CB6150>>
>>> c.x()
x method

Note that in this case __getattr__ never gets called because the name
was found using the normal lookup mechanism.  You would need to use
__getattribute__ if you want it to be called unconditionally.

> #Q4, if when I define the class use property too, then instance.name
> look up order would be?

You can't use properties in classic classes.  In a new-style class, if
you access a property, then any instance attribute with the same name
is ignored and can't be set in the first place.



More information about the Python-list mailing list