Python全局变量引用计数疑问:为何结果为4、5、4、5?
Python引用计数异常的原因解析
首先明确两个核心细节:
sys.getrefcount(obj)调用时会临时创建一个对obj的引用,所以返回的计数会比实际存在的“持久引用”多1。- Python对短字符串(比如
'my-string')会做字符串驻留(intern)——相同内容的字符串会被全局缓存复用,这个缓存本身会持有一个引用。
下面拆解你代码每一步的计数构成:
- 初始状态:
a = 'my-string'后调用getrefcount
返回值4的组成:
- 代码中字符串字面量
'my-string'本身的引用(编译阶段Python就会把该字面量加入驻留池,占1个引用) - 全局变量
a的引用(占1个) - 字符串驻留池的缓存引用(占1个)
sys.getrefcount(a)传参时生成的临时引用(占1个)
四项加起来正好是4。
创建列表
b = [a]后调用getrefcount
返回值变为5,是因为列表b的元素新增了1个对a的引用,加上之前的4个引用,总数就是5。执行
del b后调用getrefcount
列表b被销毁,它对a的引用也随之消失,所以计数回到初始的4。创建字典
c = {'key': a}后调用getrefcount
字典的value字段新增了1个对a的引用,计数再次变为5,逻辑和列表完全一致。
补充测试建议:如果用非驻留对象(比如a = object())重复这段代码,会得到更符合你预期的结果——初始getrefcount返回2(变量a的引用+临时引用),加入容器后返回3,删除容器后回到2,这时候就和你最初的预期匹配了。
内容的提问来源于stack exchange,提问作者yigitkucuk
相关产品推荐
相关产品推荐

