From: tim_one at email.msn.com (Tim Peters)
Date: Wed, 7 Apr 1999 06:05:12 GMT
Subject: Chaning instance methods
In-Reply-To: <199904070524.HAA12210@axil.hvision.nl>
References: <199904070524.HAA12210@axil.hvision.nl>
Message-ID: <000401be80bc$999f1820$699e2299@tim>
Content-Length: 1269
X-UID: 1374                                                  

[Jody Winston]
> I don't understand how to change instance methods.

That's good, because Python doesn't have such a thing <wink>.  Direct
attributes of instances are never methods without extreme trickery.  A
function becomes a method by virtue of being found in an instance's
*class's* dict.  Python was designed to allow overriding methods at the
class level, but not at the instance level.

> For example:
>
> class Foo:
>     def __init__(self):
>         self.data = 42
>     def m(self):
>         print "Foo.m"
>         print dir(self)
>
> def m2(self):
>     print "m2"
>     print dir(self)
>
> f = Foo()
> f.m()
> # this fails
> # f.m = m2
> # f.m()

Right, a direct attribute of an instance is never a method.  Except that
this "works":

import new
f.m = new.instancemethod(m2, f, Foo)
f.m()

This sets f.m to a *bound* instance method that refers to f, which Python
treats as an ordinary function when later referenced via f.m.  Without using
the "new" module, you can get the same effect via e.g.

old_Foo_m = Foo.m
Foo.m = m2
f.m = f.m  # heh heh <wink>
Foo.m = old_Foo_m

In either case, though, the value of f.m now contains a hidden reference to
f, so you've created a piece of immortal cyclic trash.

subclassing-is-a-lot-easier-ly y'rs  - tim






