Python id()函数在函数内外重赋值的行为差异原因咨询
现象底层原因解释
这个差异是CPython解释器的实现细节导致的,和Python语言规范本身无关,核心原因是函数栈帧复用+临时内存分配顺序固定,并非针对整数的全局缓存优化(40000早已超出CPython默认小整数缓存范围-5~256)。
函数场景多次赋值id一致的逻辑
- CPython调用函数时会创建对应的栈帧对象存储临时变量、执行上下文,函数执行结束后,栈帧不会被立即销毁,会被缓存下来供后续同函数调用复用,两次调用
f()实际用的是同一块内存结构的栈帧。 - 第一次调用时赋值
x=40000创建的整数对象,存储在栈帧的临时内存区,函数执行结束后该对象没有外部引用,内存被释放回当前栈帧的可用内存池。 - 第二次调用同函数时,复用了同一个栈帧,临时变量的分配顺序、每个int对象占用的内存大小完全固定,给新的
40000对象分配内存时,刚好拿到上次释放的同一块内存地址,因此id完全相同。
哪怕你在函数内新增多个临时变量,只要栈帧的临时变量分配结构没有变化,x=40000拿到的内存地址就会保持一致,所以你循环调用百万次结果都相同。
全局作用域赋值id不一致的逻辑
全局作用域的内存分配逻辑和函数栈帧完全不同:
- 全局变量存储在全局字典
globals()中,旧对象被释放后,内存会回到全局通用内存池,不会预留固定位置给同一个变量复用。 - 两次赋值相同数值的间隔中,全局内存池可能有其他内存操作打乱分配顺序,因此每次拿到的内存地址都不相同。
补充说明
这个特性完全符合Python的id唯一性规则:如果两个对象同时存活且id相同,才是同一个对象。如果你把函数内的40000对象引用传递到函数外持有,第二次调用时就不会复用这块内存,id会发生变化。
内容的提问来源于stack exchange,提问作者riemann_lebesgue
相关产品推荐
相关产品推荐

