==
Python和is
Python之间有区别吗?
是的,它们有一个非常重要的区别。
==
: 检查相等性 - 语义是等效对象(不一定是同一个对象)将测试为相等。正如文档所说:
运算符 <、>、==、>=、<= 和 != 比较两个对象的值。
is
:检查身份 - 语义是对象(保存在内存中)是对象。同样,文档说:
对象身份的运算符is
和测试:当且仅当和是同一个对象时为真。使用该函数确定对象身份。产生逆真值。is not
x is y
x
y
id()
x is not y
因此,身份检查与检查对象 ID 的相等性相同。那是,
a is b
是相同的:
id(a) == id(b)
whereid
是返回一个整数的内置函数,该整数“保证在同时存在的对象中是唯一的”(参见 参考资料help(id)
),并且 wherea
和b
是任意对象。
其他使用说明
您应该将这些比较用于它们的语义。用于is
检查身份和==
检查相等性。
所以一般来说,我们is
用来检查身份。当我们检查一个只应该在内存中存在一次的对象时,这通常很有用,在文档中称为“单例”。
用例is
包括:
None
- 枚举值(使用 enum 模块中的枚举时)
- 通常是模块
- 通常是类定义产生的类对象
- 通常由函数定义产生的函数对象
- 任何其他应该只在内存中存在一次的东西(通常都是单例)
- 一个你想要的特定对象
通常的用例==
包括:
- 数字,包括整数
- 字符串
- 列表
- 套
- 字典
- 自定义可变对象
- 在大多数情况下,其他内置的不可变对象
再次,一般用例==
是,您想要的对象可能不是同一个对象,而是可能是等价的对象
PEP 8个方向
PEP 8,标准库的官方 Python 风格指南也提到了两个用例is
:
与单例的比较None
应该总是使用is
or
is not
,而不是相等运算符。
if x
另外,当你真正的意思时要小心写作if x is not None
——例如,当测试一个默认为的变量或参数是否None
被设置为其他值时。另一个值可能具有在布尔上下文中可能为假的类型(例如容器)!
从身份推断平等
如果is
为真,则通常可以推断出相等性——从逻辑上讲,如果一个对象是它自己,那么它应该测试为与它自己等价。
在大多数情况下,这个逻辑是正确的,但它依赖于__eq__
特殊方法的实现。正如文档所说,
==
相等比较 (和)的默认行为!=
基于对象的标识。因此,具有相同身份的实例的相等比较导致相等,而具有不同身份的实例的相等比较导致不平等。这种默认行为的动机是希望所有对象都应该是自反的(即 x 是 y 意味着 x == y)。
并为保持一致性,建议:
平等比较应该是自反的。换句话说,相同的对象应该比较相等:
x is y
暗示x == y
我们可以看到这是自定义对象的默认行为:
>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)
反证词通常也是正确的——如果某些东西测试为不相等,您通常可以推断它们不是同一个对象。
由于可以自定义相等性测试,因此这种推断并不总是适用于所有类型。
一个例外
一个值得注意的例外是nan
- 它总是测试为不等于自身:
>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan # !!!!!
False
检查身份比检查相等(可能需要递归检查成员)要快得多。
但它不能代替相等,您可能会发现不止一个对象是等价的。
请注意,比较列表和元组的相等性将假定对象的身份相等(因为这是一种快速检查)。如果逻辑不一致,这可能会产生矛盾 - 因为它是nan
:
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
一个警示故事:
问题是试图用来is
比较整数。您不应假设整数的实例与通过另一个引用获得的实例相同。这个故事解释了原因。
一位评论者的代码依赖于小整数(-5 到 256 包括在内)在 Python 中是单例这一事实,而不是检查是否相等。
哇,这可能会导致一些阴险的错误。我有一些代码可以检查 a 是否为 b,因为 a 和 b 通常是很小的数字,所以可以按我的意愿工作。该错误仅在今天发生,经过六个月的生产,因为 a 和 b 终于大到不能被缓存。– gwg
它在开发中起作用。它可能已经通过了一些单元测试。
它在生产中工作 - 直到代码检查大于 256 的整数,此时它在生产中失败。
这是一个生产失败,可能在代码审查或样式检查器中发现。
让我强调一下:不要is
用来比较整数。