如果我使用 比较两个变量==
,Python 是否比较身份,如果它们不相同,那么比较值?
例如,我有两个指向同一个字符串对象的字符串:
>>> a = 'a sequence of chars'
>>> b = a
这是比较值还是只比较 id?:
>>> b == a
True
首先比较身份是有意义的,我猜是这样,但我还没有在文档中找到任何支持这一点的东西。我得到的最接近的是:
x==y
来电x.__eq__(y)
这并没有告诉我在调用x.__eq__(y)
.
如果我使用 比较两个变量==
,Python 是否比较身份,如果它们不相同,那么比较值?
例如,我有两个指向同一个字符串对象的字符串:
>>> a = 'a sequence of chars'
>>> b = a
这是比较值还是只比较 id?:
>>> b == a
True
首先比较身份是有意义的,我猜是这样,但我还没有在文档中找到任何支持这一点的东西。我得到的最接近的是:
x==y
来电x.__eq__(y)
这并没有告诉我在调用x.__eq__(y)
.
对于用户定义的类实例,is
用作备用 - 其中默认__eq__
值未被覆盖,a == b
被评估为a is b
. 这确保了比较总是有结果(除非NotImplemented
明确禁止比较)。
这是数据模型文档(强调我的)中提到的(有点倾斜 - 好点Sven Marnach ):
用户定义的类默认有
__eq__()
和__hash__()
方法;与它们相比,所有对象都比较不相等(除了它们自己)并x.__hash__()
返回一个适当的值,这样就x == y
意味着x is y
和hash(x) == hash(y)
。
您可以按如下方式进行演示:
>>> class Unequal(object):
def __eq__(self, other):
return False
>>> ue = Unequal()
>>> ue is ue
True
>>> ue == ue
False
so__eq__
必须在 之前调用id
,但是:
>>> class NoEqual(object):
pass
>>> ne = NoEqual()
>>> ne is ne
True
>>> ne == ne
True
所以id
必须在__eq__
未定义的地方调用。
您可以在 CPython implementation中看到这一点,其中指出:
/* If neither object implements it, provide a sensible default
for == and !=, but raise an exception for ordering. */
实现的“合理默认值”v
是指针和的 C 级相等比较w
,它将返回它们是否指向同一个对象。
除了@jonrsharpe 的回答:如果被比较的对象实现了,Python 首先检查身份__eq__
是错误的。
看下面的例子:
>>> x = float('nan')
>>> x is x
True
>>> x == x
False
NaN 是一个特定的东西,永远不应该与它自己比较;然而,即使在这种情况下x is x
也应该返回True
,因为is
.