使用`==`比较是否在比较值之前比较身份?

Does comparing using `==` compare identities before comparing values?

如果我使用 == 比较两个变量,Python 是否比较身份,如果不相同,则比较值?

例如,我有两个指向同一个字符串对象的字符串:

>>> a = 'a sequence of chars'
>>> b = a

这是比较值,还是只是比较 ID?:

>>> b == a
True

首先比较身份是有意义的,我想是这样,但我还没有在文档中找到任何支持这一点的内容。我得到的最接近的是 this:

x==y calls x.__eq__(y)

这并没有告诉我在调用 x.__eq__(y).

之前是否做了任何事情

对于用户定义的 class 实例,is 用作后备 - 在默认值 __eq__ 未被覆盖的情况下,a == b 被评估为 a is b。这确保了比较总是有结果(除了 NotImplemented 的情况,比较被明确禁止)。

这是(有点斜 - 好地方Sven Marnach) referred to in the data model documentation(强调我的):

User-defined classes have __eq__() and __hash__() methods by default; with them, all objects compare unequal (except with themselves) and x.__hash__() returns an appropriate value such that x == y implies both that x is y and hash(x) == hash(y).


您可以如下演示:

>>> class Unequal(object):
    def __eq__(self, other):
        return False


>>> ue = Unequal()
>>> ue is ue
True
>>> ue == ue
False

所以 __eq__ 必须在 id 之前调用,但是:

>>> class NoEqual(object):
    pass

>>> ne = NoEqual()
>>> ne is ne
True
>>> ne == ne
True

因此必须在未定义 __eq__ 的地方调用 id


你可以看到这个in the CPython implementation,其中注释:

/* If neither object implements it, provide a sensible default
   for == and !=, but raise an exception for ordering. */

实现的"sensible default"是指针vw的C级相等比较,会return 它们是否指向同一个对象。

除了@jonrsharpe 的回答:如果被比较的对象实现__eq__,那将是错误的 for Python 首先检查身份。

看下面的例子:

>>> x = float('nan')
>>> x is x 
True
>>> x == x
False

NaN 是一个特定的东西,永远不应该与自己比较;然而,即使在这种情况下 x is x 也应该 return True,因为 is 的语义。