我注意到有时候实例方法不能比较相同(使用is
而不是==
),即使它们与相同的绑定实例方法相关,例如。
>>> class A(object):
... def f(self):
... print "hi"
...
>>> a = A()
>>> f1 = a.f
>>> f2 = a.f
>>> f1 is f2
False
>>> f1 == f2
True
我最终使用==
来检查两个变量是否引用相同的绑定方法,但我想知道是否有人知道为什么is
不像我期望的那样行为?< / p>
答案 0 :(得分:2)
方法实现为descriptors - 因此,每次访问f
成员时,都会创建一个新函数。你可以通过查看他们的ID来看到这一点......
>>> class A(object):
... def f(self):
... pass
...
>>> a = A()
>>> f1 = a.f
>>> f2 = a.f
>>> id(f1)
4325305232
>>> id(f2)
4325818528
当我说通过描述符实现它们时,我的意思要清楚一点,以下表达式:
a = A()
func = a.f
相当于:
a = A()
func = A.f.__get__(a, A)
显然你不想一直写下后者,所以快捷方式非常好: - )。
话虽如此,这开始解释绑定方法如何知道self
是什么,因为a
(方法中的self
)被传递给__get__
是构造绑定方法的原因。