Adding and modifying methods at run-time

Discussion in 'Python' started by Thomas Weholt, Apr 30, 2004.

  1. Hi,

    I want to add methods to a class instance at run-time based on a base
    method, but modify one of the existing ( or add if possible ) params of the
    base method. Say a class like this :


    class A:
    def __init__(self):
    self.obj1() # some dummy object having a name attribute
    self.obj2() # some dummy object having a name attribute
    def __method1__(self, param1, param2, param3 = None):
    # use some property on param3 in some operations
    def addNewMethod(self, param1, new_obj):
    new_func = copy.copy(self.__method1__)
    # modify a copy of self.__method1__ and change the param3 to point
    new_obj
    # and add the method
    setattr(self, 'method4%s' % new_obj.name, new_func)

    use the class like so :

    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?

    Best regards,
    Thomas
    Thomas Weholt, Apr 30, 2004
    #1
    1. Advertising

  2. 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
    Diez B. Roggisch, May 1, 2004
    #2
    1. Advertising

  3. That worked great !!! Thanks alot.

    Thomas


    "Diez B. Roggisch" <> wrote in message
    news:c707s0$q4m$03$-online.com...
    > 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
    Thomas Weholt, May 2, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. denis
    Replies:
    0
    Views:
    267
    denis
    Oct 26, 2004
  2. flamesrock
    Replies:
    8
    Views:
    440
    Hendrik van Rooyen
    Nov 24, 2006
  3. Pierre Yves
    Replies:
    2
    Views:
    474
    Pierre Yves
    Jan 10, 2008
  4. Felipe Ochoa

    Inheriting and modifying lots of methods

    Felipe Ochoa, Oct 27, 2009, in forum: Python
    Replies:
    2
    Views:
    218
    Steven D'Aprano
    Oct 27, 2009
  5. Kenneth McDonald
    Replies:
    5
    Views:
    301
    Kenneth McDonald
    Sep 26, 2008
Loading...

Share This Page