我发现以下示例有点令人惊讶:
>>> class Foo:
def blah(self):
pass
>>> f = Foo()
>>> def bar(self):
pass
>>> Foo.bar = bar
>>> f.bar
<bound method Foo.bar of <__main__.Foo object at 0x02D18FB0>>
我希望绑定(bind)方法与每个特定实例相关联,并在构建时放置在其中。每个实例的绑定(bind)方法必须不同,这似乎是合乎逻辑的,这样它就知道将哪个实例传递给底层函数——而且,事实上:
>>> g = Foo()
>>> g.blah is f.blah
False
但是我对这个过程的理解显然是有缺陷的,因为我不希望将一个函数分配给一个类属性会把它放在当时已经创建的实例中。
所以,我的问题有两个方面 -
- 为什么将函数分配到类中会追溯应用于实例?实现这一点的实际查找规则和流程是什么?
- 这是语言保证的事情,还是碰巧发生的事情?
最佳答案
你想大吃一惊,试试这个:
f.blah is f.blah
没错,每次访问时,实例方法包装器都是不同的。
其实一个实例方法就是一个描述符。换句话说,f.blah
实际上是:
Foo.blah.__get__(f, type(f))
方法实际上并不存储在实例上;它们存储在类中,并动态生成方法包装器以将方法绑定(bind)到实例。
关于Python 方法查找规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11060600/