Dynamic method

Bruno Desthuilliers bruno.42.desthuilliers at wtf.websiteburo.oops.com
Tue Jul 10 10:46:25 EDT 2007


Daniel Nogradi a écrit :
>> I have an issue I think Python could handle. But I do not have the 
>> knowledge
>> to do it.
>>
>> Suppose I have a class 'myClass' and instance 'var'. There is function
>> 'myFunc(..)'. I have to add (or bind) somehow the function to the 
>> class, or
>> the instance. Any help, info or point of reference is wellcome....
> 
> How about this (note the first argument 'self' which is the instance
> itself in the second case):
> 
> 
> 
> def method_for_instance( message ):
>    print message
> 
> def method_for_class( self, message ):
>    print message
> 
> class myClass( object ):
>    pass
> 
> inst = myClass( )
> inst.method = method_for_instance
> 
> inst.method( 'hello' )

This won't work as expected:

class Bidule(object):
   def __init__(self, name):
     self.name = name

def greet(self, who):
   print "hello %s, my name is %s" % (who, self.name)

b = Bidule('Bruno')
b.greet = greet
b.greet('Daniel')

=>
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "/tmp/python-23258Nq5.py", line 10, in <module>
     b.greet('Daniel')
TypeError: greet() takes exactly 2 arguments (1 given)


The point is that Python functions are descriptor objects that, when 
looked up, return a (bound or unbound) method object wrapping 
themselves. So to attach functions as method *on a per-instance basis*, 
you either need to use new.instancemethod (as explained by Alex), or 
directly use the descriptor protocol, ie:

b.greet = greet.__get__(b)
b.greet('Daniel')
=> hello Daniel, my name is Bruno

Note that you don't need this to attach a function as method to a class 
- the descriptor protocol will then JustWork(tm).

HTH



More information about the Python-list mailing list