Python Shell与.py文件中对象Interning行为差异的原因探究
Python交互Shell与脚本中整数驻留的差异解析
首先明确:is运算符判断的是对象的身份(内存地址),而==判断的是对象的值是否相等,这是理解问题的基础。
核心原因:解释器执行模式的优化差异
Python的整数驻留(interning)是一种内存优化手段,但它的触发逻辑在**交互Shell(逐行执行)和脚本文件(整体编译)**中完全不同:
1. 交互Shell中的行为
在交互模式下,每一行代码都是被单独编译、单独执行的:
- 输入
a = 98765时,解释器创建一个值为98765的整数对象,将变量a指向它。 - 下一行输入
b = 98765时,由于这是全新的一行编译单元,解释器不会回溯检查之前是否存在相同值的整数对象,直接新建一个对象给b。 - 因此
a和b指向不同内存地址,a is b返回False。
Shell示例:
>>> a = 98765 >>> b = 98765 >>> a is b False
2. 脚本文件中的行为
运行.py脚本时,解释器会先将整个脚本编译为字节码,再执行,这个阶段会触发常量折叠与驻留优化:
- 编译时,解释器扫描脚本中所有字面量常量,发现两个
98765是完全相同的常量值,只会创建一个整数对象。 - 变量
a和b都指向这个唯一的对象,因此a is b返回True。
脚本示例:
a = 98765 b = 98765 print(a is b) # 输出True
关于"每次定义都创建新对象"的说法
你看到的Stack Overflow回答并不矛盾,这句话的前提是未触发解释器优化的场景:
- 当对象不是直接写死的字面量常量(比如通过用户输入、动态计算生成的对象),解释器不会做驻留优化,每次都会创建新对象。
- 比如在脚本中写:
这种情况下,两个98765是动态生成的,解释器不会复用对象,符合"每次定义创建新对象"的描述。a = int(input("输入数字:")) # 假设输入98765 b = int(input("输入数字:")) # 再次输入98765 print(a is b) # 输出False
另外补充:Python对小整数(默认范围-5到256)是强制预驻留的,不管是交互模式还是脚本模式,相同值的小整数变量都会指向同一个对象,这是固定规则。
内容的提问来源于stack exchange,提问作者ScriptKiddieOnAComputer
相关产品推荐
相关产品推荐

