Python浮点数内存存储疑问:为何同一值id有时相同有时不同
关于Python浮点数id相同的疑问
Python会对较小的整数进行内部缓存,而非在运行时重复创建:
id(5)
输出:
4304101544
在同一个内核中重复执行该代码,返回的id始终保持稳定:
id(5)
输出:
4304101544
我原本认为浮点数不会有这种机制,因为不可能预存所有浮点数。但执行以下代码时,两次返回的id完全相同:
id(4.33+1), id(5.33)
输出:
(5674699600, 5674699600)
过一段时间后重复执行相同代码,返回的内存地址又变为另一个相同的值:
id(4.33 + 1), id(5.33)
输出:
(4962564592, 4962564592)
请问这一现象的原因是什么?
问题解答
这不是Python对浮点数的预缓存机制,而是由Python的代码编译优化和内存管理策略共同导致的:
编译期常量折叠(Constant Folding)
当你在同一行代码里写4.33+1和5.33时,Python的字节码编译器会在编译阶段计算4.33+1的结果,发现它等于字面量常量5.33。为了优化性能,编译器会将这两个表达式指向同一个常量对象,因此它们的id完全相同。内存复用与垃圾回收
过一段时间后再次执行代码,内存地址变化但仍保持一致,是因为之前的浮点数对象已被垃圾回收器回收,对应的内存被释放。当再次编译执行时,编译器会重新创建5.33这个常量对象,占用新的内存块,但同一行内的两个表达式依然会指向这个新创建的同一对象,所以id依旧相同。
需要明确的关键点:
- 浮点数没有像小整数那样的全局缓存池,这种现象仅发生在同一编译单元内的等价常量上。
- 如果将两个表达式拆分到不同代码行执行,或者通过运行时动态计算(比如从用户输入获取值后计算),就不会出现
id相同的情况——因为此时编译器无法提前完成常量折叠优化。
可以用以下代码验证这一点:
a = 4.33 + 1 b = 5.33 print(id(a), id(b)) # 此处的id大概率不同,因为分两行赋值时,编译器不会进行跨行的常量折叠
内容的提问来源于stack exchange,提问作者Sebastian Wozny
相关产品推荐
相关产品推荐

