Function mistaken for a method

Eric Brunel eric_brunel at despammed.com
Thu Jun 1 11:56:03 EDT 2006


On Thu, 01 Jun 2006 15:07:26 +0200, bruno at modulix <onurb at xiludom.gro>  
wrote:
> Do yourself a favour : use new-style classes.
> class C(object)

I would if I could: I'm stuck with Python 2.1 for the moment (I should  
have mentionned it; sorry for that).

[snip]
>> Basically, I want an optional variant function across sub-classes of
>> the  same class.
>>
>> I did it like in C1 for a start, then I needed
>> something like  C2. The result is... surprising:
>>
>> 0
>> Traceback (most recent call last):
>>   File "func-vs-meth.py", line 18, in ?
>>     o2 = C2()
>>   File "func-vs-meth.py", line 5, in __init__
>>     self.x = self.f(0)
>> TypeError: <lambda>() takes exactly 1 argument (2 given)
>
> Not surprising at all.
>
> Functions implement the descriptor protocol[1]. When bound to a class
> and looked up via an instance, it's the __get__ method of the function
> object that get called - with the instance as param, as defined by the
> descriptor protocol. This method then return the function wrapped - with
> the instance - in an Method object - which itself, when called, returns
> the result of calling the function *with the instance as first
> parameter*. Which is how methods can work on the instance, and why one
> has to explicitly declare the instance parameter in "functions to be
> used as methods", but not explicitly pass it at call time.
>
> (please some guru correct me if I missed something here, but AFAIK it
> must be a correct enough description of method invocation mechanism in
> Python).
>
> [1] about descriptors, see:
> http://docs.python.org/ref/descriptors.html
> http://www.geocities.com/foetsch/python/new_style_classes.htm#descriptors
>
>> So the first works and o1.x is actually 0.
>
> int is not a function.
>>>> type(int)
> <type 'type'>
>
> int is a type.

Python 2.1 again:
>>> type(int)
<type 'builtin_function_or_method'>

But as someone mentionned, the problem is the same with other built-in  
functions, such as chr, even in the latest Python version.

I still find that a little counter-intuitive to have different behaviours  
for a built-in function and a Python function. I really would expect them  
to work (or not to work) the same in all situations, even if I now  
understand better how all works behind the scenes. But I'll live with it...

[snip]
> If you understood all my explanations, you now know how to solve the
> problem.
>
> Else, here the solution:
>
> class C3(C):
>   f = lambda self, x: return x

This is actually the first thing I did, but it seemed a bit weird to me to  
have a - let's say - callable with one parameter in one case and another  
with two parameters in the other one. So I finally turned my callable  
attribute into a real instance method, just for consistency.

Anyway, thanks a lot for your explanations.
-- 
python -c "print ''.join([chr(154 - ord(c)) for c in  
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"



More information about the Python-list mailing list