【发布时间】:2010-04-05 03:48:18
【问题描述】:
是否愿意这样做:
if x is y:
return True
或
if x == y
return True
“不是”也一样
【问题讨论】:
标签: python comparison
是否愿意这样做:
if x is y:
return True
或
if x == y
return True
“不是”也一样
【问题讨论】:
标签: python comparison
x is y 与 x == y 不同。
x is y 为真当且仅当id(x) == id(y)——即x 和y 必须是同一个对象(具有相同的ids)。
对于所有内置的 Python 对象(如字符串、列表、字典、函数等),如果 x is y,则 x == y 也是 True。但是,这一般不能保证。严格来说,x == y 为真当且仅当x.__eq__(y) 返回真。
例如,可以使用始终返回 False 的 __eq__ 方法定义对象 x,这将导致 x == y 返回 False,即使 x is y 也是如此。
所以底线是,x is y 和 x == y 是完全不同的测试。
举个例子:
In [1]: 0 is False
Out[1]: False
In [2]: 0 == False
Out[2]: True
PS。而不是
if x is y:
return True
else:
return False
写起来更Pythonic
return x is y
同样,
if x == y:
return True
else:
return False
可以替换为
return x == y
【讨论】:
x is y 为真之前,您需要x == y 为真是不正确的。它们是独立的测试。诚然,在实践中你很难找到一个合理的反例,但 __eq__ 特殊方法可能只返回 False 或引发异常。
x is y比较两个对象的身份,问'x和y是同一个对象的不同名字吗?'相当于id(x) == id(y)。
x == y 使用相等运算符并提出更宽松的问题'x 和y 是否相等?' 对于用户定义的类型,它等价于x.__eq__(y)。
__eq__ 特殊方法应该表示对象的“相等”,例如表示分数的类希望 1/2 等于 2/4,即使“半”对象不能具有相同的标识作为“两个季度”的对象。
请注意,不仅a == b 不暗示a is b,反之亦然。一个通常并不比另一个更严格的要求。是的,这意味着如果你真的想要,你可以让a == a 返回False,例如:
>>> a = float('nan')
>>> a is a
True
>>> a == a
False
尽管is 在实践中几乎总是比== 更具体。
【讨论】:
== 和 != 是对象值比较运算符is 和 is not 是对象 identity 比较运算符正如其他人已经说过的,is(和 is not)只有在您真正关心一对变量时指的是完全相同的对象。在大多数情况下,你根本不在乎,所以你会使用 == 和 !=。
但是,如果您查看大量 Python 代码,您可能会开始注意到,is(和 is not)更有可能在与True、False 和None 进行比较时使用。主要原因是这些对象是单例的,这意味着每个值都只有一个实例。为什么这很重要?好吧,这导致了另一个原因……速度。
对于 == 和 !=,解释器必须提取两个引用的对象才能进行比较(它们是否相同或不是),而 is 和 is not 只需检查它们所指对象的值。话虽如此,您可以看到后一对将执行得更快,因为您不必自己获取对象来进行比较。这是几年前的一次速度测试,我们得出的结论是,对于一次性,这没什么大不了的,但如果它在一个紧密的循环中被称为无数次,那么它就会开始累加。
http://mail.python.org/pipermail/tutor/2008-June/062708.html
底线是您可以使用对象身份比较来检查True、False 和None,其他所有内容都应使用直接相等运算符。我们不会在这里讨论内部整数或绑定实例方法,或类似的东西。 :-)
【讨论】:
if a == True: 比if a is True: 慢,后者又比if a: 慢(至少对于我测试中的内置类型)。通常只使用a 或not a 是最快的选择,尽管它们在语义上与a is True 或a is None 等不太一样。
1 is 1 或1 == 1?
range(-5, 256) 中使用小整数(当前)时它们都是等价的,但这些不是公开的数字,并且可以在任何版本中更改,所以只使用== 更安全除了None、True 和False(可能还有其他一些情况)以外的情况。
视情况而定。 is 和 is not 进行身份比较,这对于 None、Ellipsis 或确保两个对象相同是有好处的。否则,请使用== 或!=。
【讨论】: