class Bound(object):

    def add(self, a):
        print('add one')


bound = Bound()

print(Bound.add)
print(bound)
print(bound.add)

上述代码的输出为:

<function Bound.add at 0x10814a048>
<__main__.Bound object at 0x108a13c50>
<bound method Bound.add of <__main__.Bound object at 0x108a13c50>>

我们看到,类的方法和实例的方法,实际上不是同一个类型的对象。

即通过 类.函数名 的方式得到是未绑定方法,也叫函数。而通过 实例.函数名 得到的是绑定方法,简称方法,之所以叫绑定,是由于函数与特定的对象绑定在了一起。(在上述例子的输出中可以看到,绑定方法中绑定的正是实例 bound )。

引用非数据属性的实例属性时,会搜索该实例的类。如果名称是一个有效的函数对象,Python 会将实例对象连同函数对象打包到一个抽象的对象中,并且依据这个对象创建方法对象:这就是被调用的方法对象(绑定方法)。当使用参数列表调用方法对象时,会使用实例对象以及原有参数列表构建新的参数列表,并且使用新的参数列表调用函数对象。

所以,以绑定方式调用方法是,第一个参数(self)不是显示传递的,而是解释器隐式传递的。

bound = Bound()
bound.add(10)

等价于

bound = Bound()
Bound.add(bound, 10)

也就是通过调用未绑定方法的方式达到相应的目的时,函数的第一个参数必须显示传递。