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

Mel mwilson at the-wire.com
Thu Mar 13 20:18:31 EDT 2008


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.



More information about the Python-list mailing list