getattr(foo, 'foobar') not the same as foo.foobar?

Bruno Desthuilliers bruno.42.desthuilliers at wtf.websiteburo.oops.com
Fri Mar 14 14:06:30 CET 2008


Dave Kuhlman a écrit :
> Arnaud Delobelle wrote:
> 
>> 4.  Both points above follow from the fact that foo.bar is really a
>> function call that returns a (potentially) new object: in fact what
>> really happens is something like
> 
> Arnaud and Imri, too -
> 
> No.  foo.bar is *not* really a function/method call.
> 
>>     Foo.__dict__['bar'].__get__(foo, Foo).
>>
>> So every time foo.bar is executed an object is (or may be) created,
>> with a new id.
>>
>> HTH
> 
> I appreciate the help, but ...
> 
> Actually, it does not help, because ...
> 
> My understanding is that foo.bar does *not* create a new object.

Given your implementation, foo.bar *does* create a new object on each 
lookup. This object is an instancemethod instance, that is, a thin 
wrapper around Foo, foo and Foo.__dict__['bar']. Foo.__dict__['bar'] is 
a function instance, it's an attribute of class Foo, and the function 
class implements the descriptor protocol. So when bar is looked on a Foo 
instance, bar.__get__ is called with foo and Foo as arguments, and 
returns an instancemethod instance that has .im_self bound to foo, 
.im_class bound to Foo, and .im_func bound to Foo.__dict__['bar'].


>  All it
> does is return the value of the bar attribute of object foo.

Yes. But since function bar is a descriptor, foo.bar is a computed 
attribute, which value is a newly created instancemethod object.

>  What new
> object is being created?

An instancemethod.

> If I have:
> 
>     class Foo(object):
>         def bar(self): pass
> 
> 
> And I do:
> 
>     foo = SomeClass()
> 
> then:
> 
>     foo.bar
> 
> should return the same (identical) object everytime, no?  yes?

No.

> I'm still confused.

Then you have to learn how attribute lookup works in Python.



More information about the Python-list mailing list