整数和字符串标识
Python 对一系列整数使用内部缓存,以减少重复创建的不必要开销。
实际上,在比较整数标识时,这可能会导致混淆行为:
>>> -8 is (-7 - 1)
False
>>> -3 is (-2 - 1)
True
并使用另一个例子:
>>> (255 + 1) is (255 + 1)
True
>>> (256 + 1) is (256 + 1)
False
等什么?
我们可以看到身份操作 is
为某些整数(-3
,256
)产生 True
但对其他整数(-8
,257
)则没有。
更具体地说,[-5, 256]
范围内的整数在解释器启动期间内部缓存,并且只创建一次。因此,它们是**相同的,**并且将它们的身份与 is
的输出进行比较 True
; 超出此范围的整数(通常)是即时创建的,它们的身份与 False
相比较。
这是一个常见的陷阱,因为这是一个常见的测试范围,但通常情况下,代码在后期分段过程中失败(或更糟糕的是 - 生产),在完美开发后没有明显的原因。
解决方案是始终使用等于 (==
)运算符而不是标识(is
)运算符来比较值。
Python 还会保留对常用字符串的引用,并且在比较字符串的标识(即使用 is
)时可能会导致类似的混淆行为。
>>> 'python' is 'py' + 'thon'
True
字符串'python'
是常用的,因此 Python 有一个对象,所有对字符串'python'
的引用都使用。
对于不常见的字符串,即使字符串相等,比较标识也会失败。
>>> 'this is not a common string' is 'this is not' + ' a common string'
False
>>> 'this is not a common string' == 'this is not' + ' a common string'
True
因此,就像整数规则一样,总是使用相等 (==
)运算符而不是标识(is
)运算符来比较字符串值。