Python Cookbook question re 5.6

Sean Ross sross at connectmail.carleton.ca
Sun Dec 14 13:31:19 EST 2003


"Joe" <freak at yeah.com> wrote in message
news:SX%Cb.548624$Fm2.517912 at attbi_s04...
> The recipe in question is "Implementing Static Methods".  It shows how to
> use staticmethod().  This sentence in the Discussion section isn't clear
to
> me:  "An attribute of a class object that starts out as a Python function
> implicitly mutates into an unbound method."  I'm not sure what this means,
> exactly.  Can anyone elaborate?
>
> Thanks,
> Chris
>

Here's an example that may help show what's going on:

class C:
    def f():
        print "f"
    print type(f)

print type(C.f)
try:
    C.f()
except TypeError, e:
    print e
try:
    c = C()
    C.f(c)
except TypeError, e:
    print e


# OUTPUT
<type 'function'>
<type 'instancemethod'>
unbound method f() must be called with C instance as first argument (got
nothing instead)
f() takes no arguments (1 given)


When the class C is evaluated the "print type(f)" statement is executed. It
shows that, at that moment, f's type is 'function'.
But when you ask, "type(C.f)" it tells you that f is an instance method.
When you try to call f using "C.f()" you're told that f is an unbound
method, that must be called with an instance of C as the first argument.
When you make a method, you usually specify the first argument as being
"self". In this case "self" would be an instance of C. So, anyway, now f
appears to expect an argument when it's called. So, we try passing in what
it appears to expect "C.f(c)", and it tells us that "f() takes no arguments
(1 given)". Heh.

I'm not exactly sure what Python's doing behind the scenes but I imagine
that it's wrapping all function definitions inside the class body: something
like

for all functions in the class:
    function = unbound_method(function)

where unbound_method is a callable that maintains the original function as
an attribute. When you call the unbound_method, it delegates the call to
this function f.  It's the unbound_method that expects the "instance of C as
the first argument", but when it passes the argument to its delegate
function f - well, f doesn't take any arguments, so we get an exception.

Like I said, I don't know exactly what mechanism are being employed behind
the scenes, but this is the way I try to understand what's going on.

Hopefully this is somewhat correct, and helpful,
Sean






More information about the Python-list mailing list