Replacing methods without subclassing

Carl Banks imbosol at vt.edu
Sat Jan 25 19:30:09 EST 2003


Aum wrote:
> Hi,
> 
> I notice that when I replace a method in a class instance, by doing:
> 
>        >>>myinstance.methodname = myfunc
> 
> the new function gets called *without* the class instance as the first 
> argument.
> 
> Is there any way of changing this *without* subclassing?

I can think of a few options:

1. You could replace the method in the class object, as opposed to the
   instance object.  This, of course, will cause all objects of that
   type to get the new method.  If that's what you want, that's what
   you should do.  But if you only want one instance to have the new
   method, you'll have to try something else.

2. If you have Python 2.1 or above, you can use a closure to define a
   wrapper function.  So if you have a function that you want to use
   as a method, defined like this:

       def myfunc(self,arg1,arg2):
           ...

   You can define a function that wraps this function inside another
   that supplies the instance:

       from __future__ import nested_scopes

       def attach_method_to_instance(instance,func):
           def attached_method(*args,**kwargs):
               return func(instance,*args,**kwargs)
           return attached_method

   And then you can set myfunc to be a method of that one instance
   with the following:

       myinstance.methodname = attach_method_to_instance(myinstance,myfunc)

   Better yet, if you only need this particular behavior for one
   class, you could make attach_method_to_instance a method (replace
   instance with self).


3. You can define a wrapper class, analogous to the above example:

       class AttachedMethod:
           def __init__(self,instance,func)
               self.instance = instance
               self.func = func
           def __call__(self,*args,**kwargs):
               return self.func(self.instance,*args,**kwargs)          

       myinstance.methodname = AttachedMethod(myinstance,func)

   Not quite as smooth or efficient as the closure above, but it works
   on Pythons before 2.1.


-- 
CARL BANKS




More information about the Python-list mailing list