为什么sys.getrefcount()在Python控制台与脚本中返回值存在差异?
Python小整数引用计数在REPL和独立脚本中的差异原因
前置基础
CPython实现中,会对范围在[-5, 256]的小整数做全局驻留处理,整个解释器生命周期内,同一个小整数只会创建一个实例,你测试的11属于这个范围,所以a、b、字面量11的id完全一致,是指向同一个对象的正常表现。
1. REPL环境中三者引用计数不一致的原因
sys.getrefcount(obj)的返回值本身包含了函数调用时传入参数产生的1次临时引用,这是该函数的固定特性。- 当你传入变量a、b调用该函数时,除了函数本身的1次临时引用,不会产生额外引用,返回的17就是该对象当前的总引用数。
- 当你直接传入字面量
11调用该函数时,REPL的交互式特性会产生3次额外的临时引用:- 解析字面量表达式时产生的临时引用
- REPL对输入表达式结果的临时持有
- REPL将表达式结果存入内置变量
_产生的引用
这3次额外引用叠加后,最终返回值就变成了20,比传入变量的结果高3。
2. 独立脚本中三者引用计数一致的原因
- 独立脚本是先完整编译为字节码再批量执行,没有REPL的交互式临时持有、
_变量存储的逻辑。 - 不管你传入的是变量a、b还是字面量
11,编译后的字节码都是直接指向驻留的11实例,调用sys.getrefcount时只会产生1次参数传入的临时引用,所以三者返回结果完全一致。 - 脚本中返回的28比REPL中的17数值更高,是因为脚本执行过程中,print输出、字符串格式化操作也多次引用了11这个实例,属于正常现象。
内容的提问来源于stack exchange,提问作者mvk
相关产品推荐
相关产品推荐

