Method binding confusion

Eric Brunel eric_brunel at despammed.com
Mon May 3 04:39:59 EDT 2004


Peter Otten wrote:
> A B Carter wrote:
> 
> 
>>I'm a bit confused by the behavior of the following code:
>>
>>
>>import math
>>import myModule
>>
>>class Klass(object):
>>   def doOperation(self, x, y):
>>      return self.operator(x, y)
>>
>>class KlassMath(Klass):
>>   operator = math.pow
>>
>>class KlassMyModule(Klass):
>>   operator = myModule.pow
>>
>>km = KlassMath()
>>kmy = KlassMyModule()
>>
>>km.doOperation(2,4)
>>km.doOperation(2,4)
> 
> 
> Should that be kmy.doOperation(2,4)? Please cut and paste actual code. (The
> same goes for the tracebacks)
> 
> 
>>The last call fails with "TypeError: takes exactly 2 argumetns (3
>>given)" I understand that in KlassMyModule the operator is being
>>treated as a method and a reference to the class instance is being
>>past as the first argument. And I also understand that Python is
>>treating a function from the standard math libary differently from a
>>function I defined in my own module. What I don't understand is why.
> 
> 
> Assuming that myModule.pow (which you do not to provide) is a function that
> takes two arguments, all these will fail:
> 
> kmy.doOperation(2, 4)
> kmy.operator(2, 4)
> km.doOperation(2, 4)
> km.operator(2, 4)
> 
> If you want to avoid the automatic addition of self, use staticmethod:
> 
> 
>>>>def mypow(a, b):
>>>
> ...     return "%s ** %s" % (a, b)
> ...
> 
>>>>class MyClass:
>>>
> ...     operator = staticmethod(mypow)
> ...
> 
>>>>MyClass().operator(2, 4)
>>>
> '2 ** 4'
> 
> 
> Peter

I can reproduce the OP's behaviour with old-style classes in Python 2.1.1:

 >>> class C:
...     def op(self, x, y):
...             return self.operator(x, y)
...
 >>> import math
 >>> class C1(C):
...     operator = math.pow
...
 >>> o1 = C1()
 >>> o1.op(2, 3)
8.0
 >>> def myPow(x, y): return '%s ** %s' % (x, y)
...
 >>> class C2(C):
...     operator = myPow
...
 >>> o2 = C2()
 >>> o2.op(2, 3)
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 3, in op
TypeError: myPow() takes exactly 2 arguments (3 given)

I also cannot understand the difference between C1 and C2: math.pow and myPow 
are both functions with two parameters, so why does the first work and not the 
second? Or was it an "unwanted feature" that was removed in a later version?

I also have some difficulty to understand the "automatic addition of self" you 
mention. In what case is it needed? I would have sworn the two classes worked...
-- 
- Eric Brunel <eric (underscore) brunel (at) despammed (dot) com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com




More information about the Python-list mailing list