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. -- http://mail.python.org/mailman/listinfo/python-list