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

Peter Otten __peter__ at web.de
Fri Mar 14 04:09:37 EDT 2008


Dave Kuhlman wrote:

> 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.  All it
> does is return the value of the bar attribute of object foo.  What new
> object is being created?

If the attribute has a __get__() method that's completely under the
attribute's control:

>>> class Bar(object):
...     def __get__(self, *args):
...             print "__get__%s" % (args,)
...             return self.next()
...     def next(self):
...             self.count += 1
...             return self.count
...     count = -1
...
>>> class Foo(object):
...     bar = Bar()
...     def __repr__(self): return "foo"
...
>>> foo = Foo()
>>> foo.bar
__get__(foo, <class '__main__.Foo'>)
0
>>> foo.bar
__get__(foo, <class '__main__.Foo'>)
1
>>> foo.bar
__get__(foo, <class '__main__.Foo'>)
2
>>> getattr(foo, "bar")
__get__(foo, <class '__main__.Foo'>)
3

Peter




More information about the Python-list mailing list