getattr(foo, 'foobar') not the same as foo.foobar?
castironpi at gmail.com
castironpi at gmail.com
Thu Mar 13 21:15:19 EDT 2008
On Mar 13, 7:45 pm, castiro... at gmail.com wrote:
> On Mar 13, 7:18 pm, Mel <mwil... at the-wire.com> 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.
More information about the Python-list
mailing list