Python 为什么不';t方法是否具有引用等式?

Python 为什么不';t方法是否具有引用等式?,python,methods,identity,equality,Python,Methods,Identity,Equality,我有一个bug,在使用is时,我依赖于方法之间相等。事实证明并非如此: >>> class What: ... def meth(self): ... pass >>> What.meth is What.meth True >>> inst = What() >>> inst.meth is inst.meth False 为什么会这样?它适用于常规功能: >>> def fu

我有一个bug,在使用
is
时,我依赖于方法之间相等。事实证明并非如此:

>>> class What:
...     def meth(self):
...         pass

>>> What.meth is What.meth
True
>>> inst = What()
>>> inst.meth is inst.meth
False
为什么会这样?它适用于常规功能:

>>> def func(): pass
>>> func is func
True

每次访问方法对象时都会创建它们。函数的作用类似于,在调用其
\uuuu get\uuuu
方法时返回一个方法对象:

>>> What.__dict__['meth']
<function What.meth at 0x10a6f9c80>
>>> What.__dict__['meth'].__get__(What(), What)
<bound method What.meth of <__main__.What object at 0x10a6f7b10>>

Martijn说得对,一种新方法是由
\uu get\uu
生成的对象,因此它们的地址指针不等同于
is
求值。请注意,使用
==
将按照Python 2.7中的预期进行计算

Python2.7
class Test(object):
    def tmethod(self):
        pass

>>> Test.meth is Test.meth
False
>>> Test.meth == Test.meth
True

>>> t = Test()
>>> t.meth is t.meth
False
>>> t.meth == t.meth
True
但是请注意,从实例引用的方法并不等同于从类引用的方法,因为从实例引用的方法附带了自引用

>>> t = Test()
>>> t.meth is Test.meth
False
>>> t.meth == Test.meth
False
在Python3.3中,方法的
is
运算符的行为通常与
=
相同,因此在本例中,您得到的是预期的行为。这是由于Python3中的
\uuuu cmp\uuuu
消失和更干净的方法对象表示所导致的;方法现在有
\uuuuuuueq\uuuuuuu
,并且引用不是构建在动态对象上的,因此在没有Python 2预期的情况下,行为可能会如预期的那样

Python3.3
>>> Test.meth is Test.meth
True
>>> Test.meth == Test.meth
True
>>> Test.meth.__eq__(Test.meth)
True

这在Python3中起作用。@poke no,
What.meth是What.meth
起作用(返回
True
),但
inst=What();inst.meth是inst.meth
在Python 3.8.0上返回False如果我使用
=
我会得到我所寻找的身份平等行为吗?我认为方法平等检查
.im\u self
的身份,而不是平等@克劳迪乌:是的,对不起,它会测试
im\u self
是否相同。@Claudiu Claudiu,Martijn:你的意思是,在评论中,该方法平等检查
im\u self
im\u func
的身份,不是吗?这一点在编辑中被纠正了,不是吗?是的,两者都经过身份验证;函数只有在相同的情况下才相等。您的分析已关闭。您在Python3中观察到的更改与
is
无关;这是因为Python3中未绑定的方法对象消失了
Test.meth
现在只是您定义的原始函数对象,而不是动态创建的未绑定方法对象。啊,是的,我添加了一些澄清细节以包括未绑定对象问题。
Python3.3
>>> Test.meth is Test.meth
True
>>> Test.meth == Test.meth
True
>>> Test.meth.__eq__(Test.meth)
True