Python整数和字符串身份

示例

Python对一系列整数使用内部缓存,以减少重复创建整数所带来的不必要开销。

实际上,当比较整数标识时,这可能导致混乱的行为:

>>> -8 is (-7 - 1)
False
>>> -3 is (-2 - 1)
True

并使用另一个示例:

>>> (255 + 1) is (255 + 1)
True
>>> (256 + 1) is (256 + 1)
False

等等什么

我们可以看到,身份操作is收益率True对于一些整数(-3,256),但没有为他人(-8,257)。

更具体地说,范围[-5, 256]内的整数在解释器启动期间在内部缓存,并且仅创建一次。因此,它们是相同的,并且将其身份与is收益进行比较True;(通常)即时创建超出此范围的整数,并将其标识与进行比较False。

这是一个常见的陷阱,因为这是测试的通用范围,但是通常,在完美地进行开发工作之后,代码在后来的登台过程(或更糟糕的是生产)中失败,没有明显的原因。

解决方案是始终使用equals(==)运算符而不是identity(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)运算符比较字符串值