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