How to replace a method in an instance.
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Wed Aug 22 01:48:18 EDT 2007
kyosohma at gmail.com a écrit :
> On Aug 24, 11:02 am, "Steven W. Orr" <ste... at syslang.net> wrote:
>
>>In the program below, I want this instance to end up calling repmeth
>>whenever inst.m1 is called. As it is now, I get this error:
>>
>>Hello from init
>>inst = <__main__.CC instance at 0x402105ec>
>>Traceback (most recent call last):
>> File "./foo9.py", line 17, in ?
>> inst.m1()
>>TypeError: repmeth() takes exactly 1 argument (0 given)
>>
>>#! /usr/bin/python
>>def repmeth( self ):
>> print "repmeth"
>>
>>class CC:
>> def __init__( self ):
>> self.m1 = repmeth
>> print 'Hello from init'
>>
>> def m1 ( self ):
>> print "m1"
>>
>>inst = CC()
>>inst.m1()
>>
>>TIA
>>
>
> Remove "self" from repmeth as it's not required in a function, only in
> functions that are defined within a class.
Obviously wrong. 'self' (or whatever-you-name-it) as first arg is
mandatory for functions used as instance methods. The fact that a
function is defined outside a class doesn't mean it cannot be used as a
method...
> Of course, a function in a
> class is also know as a method.
Less obvious but still wrong !-)
A function object, whereever (and however) it's defined, is a function
object, not a method objet. Now what happens is that functions defined
inside a class are wrapped in method (by default, instancemethod) objects.
To be more accurate - and talking only about how it works for new-style
classes - function objects implements the descriptor protocol, so when a
function is a class attribute (which is what happens when the function
is defined in the class statement's body), and is looked up on an
instance, it returns an instancemethod object that has the instance and
the function as attributes. This instancemethod object is itself
callable, and when called returns the result of calling the function
with the instance as first argument. classmethods and staticmethods are
variants fo this scheme, calling the function with either the class as
first arg (for classmethods) or just as-is (for staticmethods).
Now when you set a function as an *instance* (not class) attribute, the
descriptor protocol isn't invoked (it only works on class attributes),
so if you want to use the function as a method, you have to do the
wrapping by yourself (cf my other answer to the OP).
HTH
More information about the Python-list
mailing list