odd difference calling function from class or instance variable

Chris Angelico rosuav at gmail.com
Wed Aug 13 05:45:05 EDT 2014


On Wed, Aug 13, 2014 at 7:06 PM, GregS <not at my.real.address.com> wrote:
> If you look at i.ref.__self__ for the two cases, you'll see what's going on.
> I've tried RTFMing but can't find the reason for the two behaviours.  Could
> someone provide an explanation for me, please?

What you're seeing there is the magic of instance methods. I'll
simplify it some by defining the method right there in the class,
rather than doing the weird injection that you were doing:

>>> class C:
    def meth(self):
        print("Hi! I'm a method.",self)

>>> C().meth()
Hi! I'm a method. <__main__.C object at 0x012BC6D0>
>>> C.meth
<function C.meth at 0x012AF300>
>>> C().meth
<bound method C.meth of <__main__.C object at 0x012AEDF0>>
>>> _()
Hi! I'm a method. <__main__.C object at 0x012AEDF0>

When you look up something on the instance, if there's a regular
function of that name on its class, you'll get back a piece of magic
called a bound method. It's a curried function, if you know what that
means (if you don't, just skip this sentence). When you then call that
bound method, it ultimately goes back to the original function, with a
pre-filled first argument (which comes from __self__).

Basically, what this means is that a bound method can be treated like
a function, and it automatically keeps track of its proper state; the
unbound method *is* a function, so if you call that directly, you'll
need to pass it an object as self.

>>> C.meth(C())
Hi! I'm a method. <__main__.C object at 0x0169AA70>

As a general rule, though, you won't be doing this kind of thing.
Define functions inside a class body, and then call them on instances.
Everything'll happily work, and all these little details are magic :)

ChrisA



More information about the Python-list mailing list