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

Python 2.7.x/3.6.x中相同float值的不同变量为何id()相同?

为什么这些浮点数对象的ID会相同?

这是个非常典型的Python编译优化问题,咱们结合你的测试代码和运行结果来拆解背后的机制:

首先看你运行的测试代码:

f1 = 2.0
f2 = 2.0
print (id(f1), id(f2), id(f1) == id(f2))
f1 = 2.0
f2 = 2.00
print (id(f1), id(f2), id(f1) == id(f2))
f1 = 2.0
f2 = 2.0 + 0
print (id(f1), id(f2), id(f1) == id(f2))

不同Python版本的运行结果都呈现出一致规律:前两次打印的id相同,第三次不同。核心原因是编译时常量折叠和运行时计算的区别:

  • 编译时常量折叠:字面量浮点数的合并
    Python的字节码编译器在处理代码时,会对直接写死的浮点数字面量做优化:如果两个字面量在编译阶段就能确定数值完全相等(比如2.0和2.00,本质是同一个值),编译器会让它们指向同一个内存对象,避免重复创建相同的浮点数实例。这就是前两个测试用例里f1和f2的id完全相同的原因。

  • 运行时计算:无法提前优化的表达式
    第三个用例里的2.0 + 0是需要程序运行时才能计算的表达式,虽然结果和2.0完全一致,但Python编译器不会在编译阶段提前计算这个表达式的结果(这类跨运算的逻辑不在常量折叠的规则范围内)。所以程序运行到这一行时,会新创建一个浮点数对象存储计算结果,导致f2的id和f1不同。

和整数缓存机制的区别

你提到的整数-5到256缓存机制,和浮点数的这个优化有本质不同:

  • 整数缓存是解释器层面的全局对象池,不管是字面量还是运行时计算出的整数,只要在-5到256范围内,都会复用同一个对象;
  • 而浮点数的优化只是编译阶段的字面量合并,仅针对直接书写的字面量,运行时计算出的浮点数(哪怕数值和字面量一致)都会创建新对象,也没有固定的范围限制。

另外要注意:这种优化是CPython的实现细节,其他Python解释器(比如PyPy)可能有不同处理方式,但你的测试结果在多个CPython版本里一致,说明这个行为是稳定的。

内容的提问来源于stack exchange,提问作者V. E.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:28:26