==和isPython 之间有区别吗?
是的,它们有非常重要的区别。
==:检查是否相等-语义是等效对象(不一定是同一对象)将被测试为相等。如文档所述:
运算符<,>,==,> =,<=和!=比较两个对象的值。
is:检查身份-语义是对象(保存在内存中)是对象。再次,文档说:
运算符is和is not对象身份测试:x is y当且仅当x和y是相同对象时,才为true 。使用该id()功能确定对象身份。x is not y产生反真值。
因此,对身份的检查与对对象ID的相等性检查相同。那是,
a is b
是相同的:
id(a) == id(b)
where id是返回整数的内建函数,该整数“保证同时存在的对象之间是唯一的”(请参阅参考资料help(id)),而where a和b则是任意对象。
其他使用说明
您应该将这些比较用于它们的语义。使用is检查身份和==检查平等。
因此,通常,我们使用is来检查身份。当我们检查一个仅在内存中存在一次的对象(在文档中称为“单个”)时,这通常很有用。
用例is包括:
None
- 枚举值(当使用枚举模块中的枚举时)
- 通常是模块
- 通常是由类定义产生的类对象
- 通常由函数定义产生的函数对象
- 在内存中应该只存在一次的所有其他内容(通常是所有单例)
- 您希望通过身份获得的特定对象
通常的用例==包括:
- 数字,包括整数
- 弦
- 清单
- 套
- 词典
- 自定义可变对象
- 在大多数情况下,其他内置的不可变对象
一般使用情况下,再次对==,就是你想可能不是对象相同的对象,相反,它可能是一个相当于一个
PEP 8方向
PEP 8,标准库的官方Python样式指南还提到了以下两个用例is:
与单例之类的比较None应始终使用is或
is not,而不应使用相等运算符。
另外,当心if x您的意思if x is not None,例如当测试是否将默认None
设置为的变量或参数设置为其他值时,请当心编写。另一个值可能具有在布尔上下文中可能为false的类型(例如容器)!
从身份推断平等
如果is为true,通常可以推断出相等性-从逻辑上讲,如果对象是自身,则它应该测试为等同于自身。
在大多数情况下,此逻辑是正确的,但它依赖于__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用于比较整数。
echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - foo输出:False True False。