You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何同一段Python代码在交互提示符与文件运行时id()断言结果不同?

问题解析:Python交互模式与脚本文件中id()行为差异的原因

核心原因是CPython在脚本文件和交互模式下的常量编译策略不同,导致相同字面量是否复用同一对象的逻辑有区别,和整数缓存机制无关。

1. 脚本文件中的行为:常量复用

当你在脚本文件中执行i = 12345; assert id(i) == id(12345)时,CPython的字节码编译器会进行常量折叠优化:

  • 编译器会扫描整个脚本的常量,把所有值相同的字面量(比如这里的两个12345)合并到同一个常量槽中。
  • 执行时,i被赋值为这个常量槽中的整数对象,id(12345)也是引用同一个对象,所以两者的id完全一致,断言不会触发错误。

你可以用dis模块验证字节码:

# 脚本文件list_and_int_1.py中添加以下代码
import dis
dis.dis('i = 12345; assert id(i) == id(12345)')

运行后会看到,两次LOAD_CONST指令都使用了同一个索引(比如0),说明引用的是同一个常量对象。

2. 交互模式中的行为:常量不复用

而在交互模式下,CPython的编译策略更为保守:

  • 即使是同一行代码中的相同字面量,编译器也不会将它们合并到同一个常量槽,而是会生成两个独立的常量项。
  • 执行时,i = 12345创建第一个整数对象并赋值给i,id(12345)则创建第二个全新的整数对象,两个对象的内存地址不同,所以id()返回值不一样,触发AssertionError。

同样用dis模块验证:

>>> import dis
>>> dis.dis('i = 12345; assert id(i) == id(12345)')

输出会显示两次LOAD_CONST使用了不同的索引(比如0和1),说明引用的是两个不同的常量对象。

3. 关于id()文档的准确性

CPython文档中“id()返回对象内存地址,唯一且在对象生命周期内恒定”的描述是完全准确的:

  • 在脚本模式下,两个12345是同一个对象,它的id在生命周期内始终唯一且不变;
  • 在交互模式下,两个12345是两个独立的对象,各自有唯一的id,只是它们的值相同而已。这完全符合文档的定义。

内容的提问来源于stack exchange,提问作者user7711283

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:03:27