结果是交互式Python解释器分别编译每个语句。编译不仅生成字节码,还为任何内置的不可变类型(包括整数)生成常量。这些常量作为co_consts属性与code对象一起存储。在
您的x = -10是与y = -10赋值分开编译的,最终得到完全独立的co_consts结构。另一方面,x, y = [-10, -10]iterable赋值是一个单独的赋值语句,一次传递给编译器,因此编译器可以重用常量。在
您可以将简单的语句(如赋值)放在一行之间用分号隔开,此时,在Python2.7中,您将再次获得相同的-10对象:>>> x = -10; y = -10
>>> x is y
True
在这里,我们再次编译了一个语句,因此编译器可以确定它只需要一个对象来表示-10值:
^{pr2}$
'single'是交互式解释器使用的编译模式。编译的字节码从这些常量加载-10值。在
如果你把所有的东西都放在一个函数中,编译成一个复合语句,你会得到同样的结果:>>> def foo():
... x = -10
... y = -10
... return x is y
...
>>> foo()
True
>>> foo.__code__.co_consts
(None, -10)
模块也可以一次性编译,因此模块中的全局变量可以共享常量。在
所有这些都是一个实现细节。你应该永远不要指望这个。在
例如,在Python3.6中,一元减号运算符是单独处理的(而不是-10被视为单个整数文本),并且在窥视孔优化过程中,在常量折叠之后达到-10值。这样可以得到两个独立的-10值:>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=6, micro=3, releaselevel='final', serial=0)
>>> compile('x = -10; y = -10', '', 'single').co_consts
(10, None, -10, -10)
其他Python实现(pypyy、Jython、IronPython等)可以再次自由地以不同的方式处理常量。在