Python中的==和is之间有区别吗?
我的Google-fu使我失败了。
在Python中,以下两个相等测试是否等效?
n = 5 # Test one. if n == 5: print 'Yay!' # Test two. if n is 5: print 'Yay!'
这是否适用于我们要比较实例的对象(例如"列表")?
好的,这样可以回答我的问题:
L = [] L.append(1) if L == [1]: print 'Yay!' # Holds true, but... if L is [1]: print 'Yay!' # Doesn't.
因此," =="测试值是"测试"的地方,以查看它们是否是同一对象?
解决方案
" =="确定值是否相等,而" is"确定它们是否是完全相同的对象且相等。
https://docs.python.org/library/stdtypes.html#comparisons
是对身份进行测试==
测试是否相等
每个(小)整数值都映射到一个值,因此,每3个相同且相等。这是一个实现细节,虽然不是语言规范的一部分
如果两个变量指向同一个对象,则" is"将返回" True";如果变量所引用的对象相等,则" =="。
>>> a = [1, 2, 3] >>> b = a >>> b is a True >>> b == a True >>> b = a[:] >>> b is a False >>> b == a True
在情况下,第二个测试仅能工作,因为Python会缓存小的整数对象,这是实现细节。对于较大的整数,这不起作用:
>>> 1000 is 10**3 False >>> 1000 == 10**3 True
字符串文字也是如此:
>>> "a" is "a" True >>> "aa" is "a" * 2 True >>> x = "a" >>> "aa" is x * 2 False >>> "aa" is intern(x*2) True
也请参阅此问题。
回答是正确的。 " is"运算符比较两个对象的身份。 " =="运算符比较两个对象的值。
一旦创建了对象,其身份就永远不会改变。我们可能会认为它是对象在内存中的地址。
我们可以定义" cmp"方法或者诸如" eq"之类的丰富比较方法来控制对象值的比较行为。
他们是完全不同的。 " is"检查对象身份,而" =="检查是否相等(取决于两个操作数的类型的概念)。
幸运的巧合是,"is
"似乎可以正确地与小整数一起使用(例如5 == 4 + 1)。那是因为CPython通过使整数成为单例来优化整数存储范围(-5到256)。此行为完全取决于实现,并且不能保证在所有较小的转换操作方式下都可以保留该行为。
例如,Python 3.5还使短字符串单例,但是将它们切片会破坏此行为:
>>> "foo" + "bar" == "foobar" True >>> "foo" + "bar" is "foobar" True >>> "foo"[:] + "bar" == "foobar" True >>> "foo"[:] + "bar" is "foobar" False
看一下Stack Overflow的问题Python的is操作符对整数的表现异常。
它主要归结为"`is"检查它们是否是同一对象,而不只是彼此相等(低于256的数字是特例)。
有一条简单的经验法则可以告诉我们何时使用" =="或者" is"。
- " =="用于价值平等。当我们想知道两个对象是否具有相同的值时,请使用它。
- " is"用于参考相等性。当我们想知道两个引用是否引用同一对象时,请使用它。
通常,当我们将某种事物与简单类型进行比较时,通常会检查值是否相等,因此应使用==。例如,示例的目的可能是检查x是否具有等于2(==
)的值,而不是检查x是否从字面上指向与2相同的对象。
其他注意事项:由于CPython参考实现的工作方式,如果我们错误地使用is
来比较整数的参考相等性,则会得到意想不到且不一致的结果:
>>> a = 500 >>> b = 500 >>> a == b True >>> a is b False
这几乎就是我们所期望的:a
和b
具有相同的值,但是是不同的实体。但是呢?
>>> c = 200 >>> d = 200 >>> c == d True >>> c is d True
这与先前的结果不一致。这里发生了什么?事实证明,出于性能原因,Python的参考实现将-5..256范围内的整数对象作为单例实例进行缓存。这是一个演示此示例:
>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i))); ... 250: True 251: True 252: True 253: True 254: True 255: True 256: True 257: False 258: False 259: False
这是不使用is
的另一个明显原因:当我们错误地将其用于值相等时,该行为应由实现决定。
就像约翰·费米内拉(John Feminella)所说,大多数时候,我们将使用==和!=,因为目标是比较值。我只想对剩下的时间做些什么:
仅存在一个NoneType实例,即None是单例。因此," foo == None"和" foo is None"的含义相同。但是," is"测试更快,Pythonic约定使用" foo is None"。
如果我们要对垃圾回收进行自省或者处理,或者检查自定义构建的字符串实习小工具是否正常工作,那么我们可能有一个使用foo的用例是bar。
True和False也是(现在)单例,但是对于foo == True没有用例,对于foo是True也没有用例。