我希望能够测试两个可调用对象是否相同.我更喜欢身份语义(使用"是"运算符),但我发现当涉及方法时,会发生不同的事情.
#(1) identity and equality with a method
class Foo(object):
def bar(self):
pass
foo = Foo()
b = foo.bar
b == foo.bar #evaluates True. why?
b is foo.bar #evaluates False. why?
Run Code Online (Sandbox Code Playgroud)
我用Python 2.7和3.3(CPython)重现了这一点,以确保它不是旧版本的实现细节.在其他情况下,身份测试按预期工作(翻译会议从上面继续):
#(2) with a non-method function
def fun(self):
pass
f = fun
f == fun #evaluates True
f is fun #evaluates True
#(3) when fun is bound as a method
Foo.met = fun
foo.met == fun #evaluates False
foo.met is fun #evaluates False
#(4) with a callable data …Run Code Online (Sandbox Code Playgroud) 我有一个错误,我在使用时依赖于彼此相等的方法is.事实证明并非如此:
>>> class What(object):
def meth(self):
pass
>>> What.meth is What.meth
False
>>> inst = What()
>>> inst.meth is inst.meth
False
Run Code Online (Sandbox Code Playgroud)
为什么会这样?它适用于常规功能:
>>> def func():
pass
>>> func is func
True
Run Code Online (Sandbox Code Playgroud) Python 2.6.5(r265:79063,2012年10月1日,22:07:21)[GCC 4.4.3]
>>> class myclass:
... def func(self):
... pass
>>> dd = myclass.func
>>> ee = myclass.func
>>> cc = myclass.func
>>> ff = myclass.func
>>> ss = myclass.func
>>> uu = myclass.func
>>> pp = myclass.func
>>>
>>>
>>> id(dd) ; id(cc) ; id(ee) ; id(ff) ; id(ss) ; id(uu) ; id(pp)
3074535252L
3074534772L
3074522444L
3074531732L
3074497588L
3073003604L
3073003724L
Run Code Online (Sandbox Code Playgroud)
为什么每次绑定方法的ID都不同?
不应该一样吗?