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)
也就是通过调用未绑定方法的方式达到相应的目的时,函数的第一个参数必须显示传递。