From: Vladimir.Marangozov at inrialpes.fr (Vladimir Marangozov) Date: Thu, 08 Apr 1999 05:56:52 +0200 Subject: Chaning instance methods References: Message-ID: <370C2904.A6F4BD54@inrialpes.fr> Content-Length: 2832 X-UID: 319 Jody Winston wrote: > > I don't understand how to change instance methods. For example: > ... > What am I forgetting? On a first thought, you seem to forget Python's internals (that you're supposed to forget, BTW) and people helped you generously on this by introducing you, and me, to trickery. On a second thought, I'll follow their example ;-) but I'll try to do it the easy (OO) way; it's easy enough not to be described so far, but it seems more logical to me, so here goes. If Foo is a class and f is an instance of Foo, by changing the instance method f.m (for whatever insane reason), one augments f's behavior beyond the limits prescribed by Foo. By doing so, one withdraws f from the set of "similar" objects, instances of Foo, that share a common set of properties (operations), defined by the Foo class. (right, this is Object theory). Indeed, f becomes some particular object which is no more part of the Foo gang. Pushing that further, we have reasons to believe that after the change, we're in a situation where f belongs to some Bar gang, where Foo and Bar differ only in the 'm' method, just like if f were an instance of Bar from the start. In fact, it is Bar that has the desired augmented interface, not f. Bar is the incarnation of the desired incremental code evolution done the OO way through class inheritance (not with instance hacking). Thus we arrive at the easy & boring solution, which goes along these lines: (it's an instance hack too, but a recognized one in metaobject communities) >>> class Foo: ... def m(self): ... print "Foo.m" ... >>> f = Foo() >>> f.m() Foo.m >>> >>> def m2(self): ... print "m2" ... >>> class Bar(f.__class__): pass ... >>> Bar.m = m2 >>> >>> f.__class__ = Bar # f changes its camp >>> f.m() m2 Since we do ignore Python's internals, we do not notice that the price to pay by f for deserting the Foo gang & joining Bar's is an additional level of indirection for all accesses to Foo's methods. The good news are that if f is really a rebel instance and it wants to change camps frequently, one can use the dedicated Bar proxy class for storing new methods at will, without affecting Foo, nor its instances. In a sense, this also avoids the tricky solutions resulting from peculiarities of the class/instance implementation -- a good candidate for major changes in Python2. We won't escape these changes, unless we manage to increase bus traffic around CNRI or so ;-) To make a long story short, what you're trying to do is not very cool, so perhaps you don't get truly cool answers, but still, you can do it in Python. Fortunately, what you're asking here is not common practice, I hope! -- Vladimir MARANGOZOV | Vladimir.Marangozov at inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252