Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #18179 > unrolled thread

About instance.name look up order

Started byPrim <ukim86@gmail.com>
First post2011-12-29 08:07 -0800
Last post2011-12-29 11:35 -0700
Articles 3 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  About instance.name look up order Prim <ukim86@gmail.com> - 2011-12-29 08:07 -0800
    Re: About instance.name look up order Kev Dwyer <kevin.p.dwyer@gmail.com> - 2011-12-29 18:03 +0000
    Re: About instance.name look up order Ian Kelly <ian.g.kelly@gmail.com> - 2011-12-29 11:35 -0700

#18179 — About instance.name look up order

FromPrim <ukim86@gmail.com>
Date2011-12-29 08:07 -0800
SubjectAbout instance.name look up order
Message-ID<a0bb7fc6-b5db-4f02-bd3a-348ee0175b0e@r13g2000prr.googlegroups.com>
First, sorry about my poor english.
Put these in IPython under ubuntu.
-------------------------------------------------------------------------------------
class C:
    def __init__(self):
        self.x = 1
    def print(self):
        print self.x
c = C()
c.x --> 1, so c.x mean a attr of c named 'x'
c.print() --> pirnt 1, so c.print mean a method of c named 'print'
-------------------------------------------------------------------------------------
class C:
    def __init__(self):
        self.x = 1
    def x(self):
        print 'x method'
    def y(self):
        print 'y method'
c = C()
c.x --> 1
c.x() --> TypeError: 'int' object is not callable
c.y --> bound method C.y
#Q1: instance.name will get the attr first, than method?
-------------------------------------------------------------------------------------
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?

t = c.x
t --> print in __getattr__ method, then throw TypeError: 'str' object
is not callable
t() --> print x method
t = c.x() --> print x method, t == None
#Q3 why t=c.x() and c.x() output different?

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

Thanks for your reply.

[toc] | [next] | [standalone]


#18186

FromKev Dwyer <kevin.p.dwyer@gmail.com>
Date2011-12-29 18:03 +0000
Message-ID<mailman.4228.1325181818.27778.python-list@python.org>
In reply to#18179
Prim wrote:

> First, sorry about my poor english.
> Put these in IPython under ubuntu.
> 
-------------------------------------------------------------------------------------
> class C:
>     def __init__(self):
>         self.x = 1
>     def print(self):
>         print self.x
> c = C()
> c.x --> 1, so c.x mean a attr of c named 'x'
> c.print() --> pirnt 1, so c.print mean a method of c named 'print'
> 
-------------------------------------------------------------------------------------
> class C:
>     def __init__(self):
>         self.x = 1
>     def x(self):
>         print 'x method'
>     def y(self):
>         print 'y method'
> c = C()
> c.x --> 1
> c.x() --> TypeError: 'int' object is not callable
> c.y --> bound method C.y
> #Q1: instance.name will get the attr first, than method?
> 
-------------------------------------------------------------------------------------
> 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?
> 
> t = c.x
> t --> print in __getattr__ method, then throw TypeError: 'str' object
> is not callable
> t() --> print x method
> t = c.x() --> print x method, t == None
> #Q3 why t=c.x() and c.x() output different?
> 
> #Q4, if when I define the class use property too, then instance.name
> look up order would be?
> 
> Thanks for your reply.

Hello,

Python always looks for attributes in the instance first, then in the class,
and then in the class's superclasses.  In your first example, by defining
"x" in C.__init__ you are creating an instance attribute named "x".  When 
the attribute c.x is requested, Python finds an attribute "x" in the 
instance and returns it; the method "x" is found in the class, but the 
attribute lookup does not proceed this far.

Try looking at C.__dict__ and c.__dict__ in the interpreter to see how the 
attributes are stored.  

See also 
http://docs.python.org/reference/datamodel.html#customizing-attribute-access

Cheers

Kev

[toc] | [prev] | [next] | [standalone]


#18187

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-12-29 11:35 -0700
Message-ID<mailman.4230.1325183782.27778.python-list@python.org>
In reply to#18179
On Thu, Dec 29, 2011 at 9:07 AM, Prim <ukim86@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.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web