Adding and modifying methods at run-time

Diez B. Roggisch deetsNOSPAM at web.de
Sat May 1 09:17:54 EDT 2004


Thomas Weholt wrote:
> a = A()
> a.addNewMethod(1, a.obj1)
> # use new dynamically method
> a.method4obj1(1,2) # now the third param with a default is set to point to
> obj1 instead of None
> 
> I'm crashing at the copy-method in addNewMethod. It crashes with the
> exception "TypeError: function() takes at least 2 arguments (0 given)".
> This is deep inside the copy-module.
> 
> Any hints or clues?

I have to admit that I'm not fully undestanding what your code above is
supposed to do - but form what  I understand you try to introduce a new
method on an object where a certain named parameter is bound to a special
value.

Now this problem can be split into two parts:

1 - create a method that has a paramter bound to a certain value
2 - add that method to an object instance

The first thing is known as currying, and there is a cookbook recipe that
does that very well:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549

You will end up with a new method that can be invoked. Now to make this an
instance method, remove the space between the last two words before the
comma in this sentence and look up the result in the python docs :)

Seriously, all you need is the function instancemethod from the module new.
Use it to create a new method on your instance.

The following program illustrates the concepts, the curry-fun is  taken from
the recipes comments:

import new

def curry(*args, **create_time_kwds):
    func = args[0]
    create_time_args = args[1:]
    def curried_function(*call_time_args, **call_time_kwds):
        args = create_time_args + call_time_args
        kwds = create_time_kwds.copy()
        kwds.update(call_time_kwds)
        return func(*args, **kwds)
    return curried_function


class foo:
    def method(_, arg1, named_arg=None):
        print (arg1, named_arg)

f = foo()

f.method(1)

new_m = curry(foo.method, named_arg="something")

new_m(f,2)

f.new_m = new.instancemethod(new_m, f, foo)

f.new_m(3)




-- 
Regards,

Diez B. Roggisch



More information about the Python-list mailing list