Diez B. Roggisch wrote: >> My understanding is that foo.bar does *not* create a new object. > > Your understanding is not correct. > >> All it >> does is return the value of the bar attribute of object foo. What new >> object is being created? > > A bound method. This happens through the descriptor-protocol. Please see > this example: > > > class Foo(object): > def bar(self): > pass > > > f = Foo() > a = Foo.bar > b = f.bar > c = f.bar > > print a, b, c > print id(b), id(c)
(What Diez said.) From what I've seen, f.bar creates a bound method object by taking the unbound method Foo.bar and binding its first parameter with f. This is a run-time operation because it's easy to re-assign some other function to the name Foo.bar, and if you do, the behaviour of f.bar() will change accordingly. You can get some very useful effects from these kinds of games. You can make f into a file-like object, for example, with import sys f.write = sys.stdout.write Here, f.write *is* a straight attribute of f, although it's a built-in method of the file class. It's still bound, in a way, to sys.stdout. I'm assuming that a different example could create an attribute of f that's a bound method of some other object entirely. I've verified that f.write('howdy') prints 'howdy' on standard output. Mel. -- http://mail.python.org/mailman/listinfo/python-list