On Mar 13, 7:45 pm, [EMAIL PROTECTED] wrote: > On Mar 13, 7:18 pm, Mel <[EMAIL PROTECTED]> wrote: > > > > > > > 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. > > Accordingly, > > f.write= types.MethodType( sys.stdout.__class__.write, sys.stdout ). > > It depends on what you want the implicit first (self) to be-- f or > sys.stdout. > > But how come this works? > > >>> import types > >>> import sys > > >>> class C: > > ... write= sys.stdout.write > ... def g( self ): > ... self.write( 'was in \'g\'\n' ) > ...>>> c= C() > >>> c.g() > > was in 'g' > > Shouldn't 'write' be getting extra parameters? Sounds fishy, not to > mix metaphors.
Ah. Because this doesn't. >>> class C: ... write= sys.stdout.__class__.write #<-- ... def g( self ): ... self.write( 'was in \'g\'\n' ) ... >>> c= C() >>> c.g() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in g File "c:\programs\python\lib\io.py", line 1236, in write if self.closed: AttributeError: 'C' object has no attribute 'closed' >>> That is, because sys.stdout.write is -not- a user-defined function. What it is, is a bound member function, and only the former is converted/wrapped/bound*, as it is in the subsequent example. */ whatever. -- http://mail.python.org/mailman/listinfo/python-list