整数对象标识测试:大正负整数之间的不一致行为

Pen*_*eng 3 python python-internals

我正在使用Anaconda(Python 3.6).

在交互模式下,我对正整数> 256进行了对象标识测试:

# Interactive test 1
>>> x = 1000
>>> y = 1000
>>> x is y
False
Run Code Online (Sandbox Code Playgroud)

显然,在单独的行中写入的大整数(> 256)不会在交互模式下重复使用.

但是如果我们在一行中编写赋值,则重用大的正整数对象:

# Interactive test 2
>>> x, y = 1000, 1000
>>> x is y
True
Run Code Online (Sandbox Code Playgroud)

也就是说,在交互模式下,在一行或单独的行中写入整数赋值会对重用整数对象(> 256)产生影响.对于[-5,256]中的整数(如https://docs.python.org/2/c-api/int.html所述),缓存机制确保只创建一个对象,无论赋值是否相同或不同的线条.

现在让我们考虑小于-5的小负整数(任何超出范围[-5,256]的负整数都可以达到目的),出现了令人惊讶的结果:

# Interactive test 3
>>> x, y = -6, -6
>>> x is y
False     # inconsistent with the large positive integer 1000

>>> -6 is -6
False

>>> id(-6), id(-6), id(-6)
(2280334806256, 2280334806128, 2280334806448)

>>> a = b =-6
>>> a is b
True    # different result from a, b = -6, -6
Run Code Online (Sandbox Code Playgroud)

显然,这表明大正整数(> 256)和小负整数(<-5)之间的对象身份测试不一致.对于小的负整数(<-5),以a,b = -6,-6和a = b = -6的形式写入也有所不同(相反,它不是哪种形式用于大整数).对这些奇怪行为的任何解释?

为了比较,让我们继续IDE运行(我使用PyCharm使用相同的Python 3.6解释器),我运行以下脚本

# IDE test case
x = 1000
y = 1000
print(x is y) 
Run Code Online (Sandbox Code Playgroud)

它打印True,与交互式运行不同.感谢@Ahsanul Haque,他已经对IDE运行和交互式运行之间的不一致给出了很好的解释.但是仍然要回答我关于交互式运行中大正整数和小负整数之间不一致的问题.

Ahs*_*que 5

仅为特定源代码创建特定常量的一个副本,并在需要时进一步重用.所以,在pycharm中,你得到x is y== True.

但是,在翻译中,事情是不同的.这里,只有一行/语句一次运行.为每个新行创建一个特定常量.它不会在下一行中重复使用.所以,x is not y在这里.

但是,如果您可以在同一行中初始化,则可以具有相同的行为(重用相同的常量).

>>> x,y = 1000, 1000
>>> x is y
True
>>> x = 1000
>>> y = 1000
>>> x is y
False
>>> 
Run Code Online (Sandbox Code Playgroud)

编辑:

块是一段Python程序文本,作为一个单元执行.

在IDE中,整个模块立即执行,即整个模块是一个块.但在交互模式下,每条指令实际上是一次执行的代码块.

正如我之前所说,一个特定的常量为一段代码创建一次,如果再次出现在该代码块中则重用.

这是IDE和解释器之间的主要区别.

那么,为什么实际的解释器为较小的数字提供与IDE相同的输出?这就是整数缓存的考虑因素.

如果数字较小,则将它们缓存并在下一个代码块中重用.因此,我们在IDE中获得相同的ID.

但如果它们更大,它们就不会被缓存.而是创建一个新副本.所以,正如预期的那样,id是不同的.

希望现在有意义,