9.3.4. 方法对象

通常,方法在绑定后立即被调用:

  1. x.f()

MyClass 示例中,这将返回字符串 'hello world'。 但是,立即调用一个方法并不是必须的: x.f 是一个方法对象,它可以被保存起来以后再调用。 例如:

  1. xf = x.f
  2. while True:
  3. print(xf())

将继续打印 hello world,直到结束。

当一个方法被调用时到底发生了什么? 你可能已经注意到上面调用 x.f() 时并没有带参数,虽然 f() 的函数定义指定了一个参数。 这个参数发生了什么事? 当不带参数地调用一个需要参数的函数时 Python 肯定会引发异常 —- 即使参数实际未被使用…

实际上,你可能已经猜到了答案:方法的特殊之处就在于实例对象会作为函数的第一个参数被传入。 在我们的示例中,调用 x.f() 其实就相当于 MyClass.f(x)。 总之,调用一个具有 n 个参数的方法就相当于调用再多一个参数的对应函数,这个参数值为方法所属实例对象,位置在其他参数之前。

如果你仍然无法理解方法的运作原理,那么查看实现细节可能会澄清问题。 当一个实例的非数据属性被引用时,将搜索实例所属的类。 如果被引用的属性名称表示一个有效的类属性中的函数对象,会通过打包(指向)查找到的实例对象和函数对象到一个抽象对象的方式来创建方法对象:这个抽象对象就是方法对象。 当附带参数列表调用方法对象时,将基于实例对象和参数列表构建一个新的参数列表,并使用这个新参数列表调用相应的函数对象。