Python 在比较值之前,是否使用“==”比较标识?

Python 在比较值之前,是否使用“==”比较标识?,python,identity,equality-operator,Python,Identity,Equality Operator,如果我使用==比较两个变量,Python是否会比较标识,如果它们不相同,则比较值 例如,我有两个字符串指向同一个字符串对象: >>> a = 'a sequence of chars' >>> b = a 这是比较值还是仅比较ID >>> b == a True 首先比较身份是有意义的,我想是这样的,但我还没有在文档中找到任何支持这一点的东西。我得到的最接近的结果是: x==y调用x.\uuu eq\uuuu(y) 它不会告诉我在调用x之

如果我使用
==
比较两个变量,Python是否会比较标识,如果它们不相同,则比较值

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

>>> a = 'a sequence of chars'
>>> b = a
这是比较值还是仅比较ID

>>> b == a
True
首先比较身份是有意义的,我想是这样的,但我还没有在文档中找到任何支持这一点的东西。我得到的最接近的结果是:

x==y
调用
x.\uuu eq\uuuu(y)


它不会告诉我在调用
x之前是否做了任何事情。
eq\uuuuuuuuuuuuuuuy
对于用户定义的类实例,
是用作回退的-在默认的
\uuueq\uuuuuuuuuuu
没有被覆盖的情况下,
a==b
被评估为
a是b
。这确保了比较总是有结果(除非在
未实现的情况下,明确禁止比较)

这是(我的重点)中提到的(有点间接的-好点):

用户定义的类通过 违约使用它们,所有对象都比较不相等(除了 本身)
x.\uuuu hash\uuuu()
返回适当的值,例如
x==y
意味着
x是y
hash(x)==hash(y)


您可以通过以下方式进行演示:

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


>>> ue = Unequal()
>>> ue is ue
True
>>> ue == ue
False
因此,必须在
id
之前调用
\uuuuuuuuueq\uuuuuuu
,但是:

>>> class NoEqual(object):
    pass

>>> ne = NoEqual()
>>> ne is ne
True
>>> ne == ne
True
因此,在未定义
\uuuuu eq\uuu
的情况下,必须调用
id


您可以看到以下内容:

/*如果两个对象都没有实现它,请提供一个合理的默认值
对于==和!=,但提出一个订购例外*/

实现的“合理默认值”是指针
v
w
的C级相等比较,这将返回它们是否指向同一个对象。

除了@jonrsharpe的答案之外:如果被比较的对象实现
\uuueq\uu
,Python首先检查标识是错误的

请看以下示例:

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

NaN是一个特定的东西,永远不应该与它自己相比;但是,即使在这种情况下,
x是x
也应该返回
True
,因为
is
的语义

Python退回到相等-如果未定义
\uuuuueq\uuuu
a==b
的计算结果为
a is b
,以确保比较始终有结果。@jornsharpe这是我所期望的。它被记录在任何地方吗?@Jornsharpe事实上,不,这不是我所期望的。如果定义了
\uuuuu eq\uuuuu
,它不会先检查
id
吗?因此,如果我们正在实现
\uuuuuuueq\uuuuu
,而且这很有意义,我们是否应该先检查
id
?@PeterWood您可以这样做,是的-在比较复杂的地方,它肯定会更复杂efficient@jonrsharpeCpython在线解释了这一点!我检查了代码中的字符串。python非常感谢您的指导。回到用户定义类的对象标识并不是CPython实现的细节。这是语言规范的一部分,但在中有记录。嗯,是的,NaN是一个例外。在许多情况下,Python确实假定对象标识意味着相等。这些情况通常会导致
float('nan')
的意外行为,例如在\u float的列表中使用或检查
float('nan')
(如果您要检查的确切
float('nan')
对象在列表中,而不是在任何nan中,后者只会产生
True
)。因此,认为Python首先检查标识是“错误的”的观点似乎有点站不住脚。