Bound Unbound And Static Method In Python

先看下面一段代码

class A:
    def foo(self):
        pass
a = A()
print A.foo
print a.foo

输出

<unbound method A.foo>
<bound method A.foo of <__main__.A instance at 0x10b06a560>>

这里的关键字是 unbound 和 bound。在一个 Python 2.3.4 的文档中,它们的定义是这样的

Methods are functions that are called using the attribute notation. There are two flavors: built-in methods (such as append() on lists) and class instance methods.

...

Class instance methods are either bound or unbound, referring to whether the method was accessed through an instance or a class, respectively.

...

在 ptyhon mail list 中Kalle Svensson对 bound / unbound methods 的解释简明易懂:


Consider a function and a method:

def f(x):
    print x

class C:
    def m(self, x):
        print x

The function takes one argument and prints it, so does the method, if used on an instance:

>>> c = C()
>>> f(1)
1
>>> c.m(1)
1

This means the first method argument, self, appeared from nowhere. This is because the method is bound to the instance c. When a method is not bound to any instance, you have to supply all arguments yourself, like:

>>> C.m(c, 1)
1

This also means that c.m and C.m are not the same thing. They're almost the same, but c.m is bound to the instance c, and C.m is unbound.


而 Stackoverflow 上 Armin Ronacher 给出了更加深入的解释,非常值得一读

以下为全文引用:

Methods in Python are a very, very simple thing once you understood the basics of the descriptor system. Imagine the following class:

class C(object):
    def foo(self):
        pass

Now let's have a look at that class in the shell:

>>> C.foo
<unbound method C.foo>
>>> C.__dict__['foo']
<function foo at 0x17d05b0>

As you can see if you access the foo attribute on the class you get back an unbound method, however inside the class storage (the dict) there is a function. Why's that? The reason for this is that the class of your class implements a getattribute that resolves descriptors. Sounds complex, but is not. C.foo is roughly equivalent to this code in that special case:

>>> C.__dict__['foo'].__get__(None, C)
<unbound method C.foo>

That's because functions have a get method which makes them descriptors. If you have an instance of a class it's nearly the same, just that None is the class instance:

>>> c = C()
>>> C.__dict__['foo'].__get__(c, C)
<bound method C.foo of <__main__.C object at 0x17bd4d0>>

Now why does Python do that? Because the method object binds the first parameter of a function to the instance of the class. That's where self comes from. Now sometimes you don't want your class to make a function a method, that's where staticmethod comes into play:

class C(object):
    @staticmethod
    def foo():
        pass

The staticmethod decorator wraps your class and implements a dummy get that returns the wrapped function as function and not as a method:

>>> C.__dict__['foo'].__get__(None, C)
<function foo at 0x17d0c30>

Hope that explains it.

=== End of Quote ===