sys.getrefcount() 的返回值

6 投票
3 回答
3897 浏览
提问于 2025-04-17 03:01

为什么

sys.getrefcount() 

对于每一个大数字或者简单字符串,它总是返回3?这是不是意味着程序里有3个对象存在?还有,为什么把x设置为(一个非常大的数字)并不会增加那个对象的引用计数?那3个引用计数是因为我调用了getrefcount吗?谢谢你帮我解释这个。

比如:

>>> sys.getrefcount(4234234555)
3
>>> sys.getrefcount("testing")
3
>>> sys.getrefcount(11111111111111111)
3
>>> x=11111111111111111
>>> sys.getrefcount(11111111111111111)
3 

3 个回答

1

看起来,当你把一个直接的数字作为参数传给sys.getrefcount时,实际上有3个引用:

  • 一个是对象本身的引用(逻辑上的);
  • 一个是临时的引用,用于传递给sys.getrefcount的对象;
  • 还有一个我猜是临时的引用,给解释器用的,它把原始的数字(或者字符串,或者其他任何东西)转换成可以理解的对象。

举个例子,我们来看这个:

>>> sys.getrefcount(123456)
3

>>> a = 123456
>>> sys.getrefcount(a)
2

我不太清楚Python内部到底是怎么想的,但这确实很有趣。我只能猜测,原始的整数(引用#1)会暂时转换成一个int对象(引用#2),然后这个对象作为参数传给sys.getrefcount(引用#3)。

6
  1. 为了节省创建对象的时间,Python会对小字符串和整数进行缓存。

  2. 当你在交互式Python解释器中输入内容时,它会暂时保存你输入的每个字面量的引用。比如,比较一下 getrefcount('foobar')getrefcount('foo' + 'bar')。在后者的情况下,解释器会分别保存 'foo''bar' 的引用。

  3. 来自手册的说明:

返回的计数通常比你预期的要多1,因为它还包括作为参数传递给 getrefcount() 的(临时)引用。

13

大整数对象不会被解释器重复使用,所以你会得到两个不同的对象:

>>> a = 11111
>>> b = 11111
>>> id(a)
40351656
>>> id(b)
40351704

sys.getrefcount(11111) 总是返回相同的数字,因为它测量的是一个新对象的引用计数。

对于小整数,Python总是会重复使用同一个对象:

>>> sys.getrefcount(1)
73

通常你只会得到一个新对象的引用:

>>> sys.getrefcount(object())
1

但是,Python为了提高性能,会在一个特别的预分配区域分配整数,我怀疑这额外的两个引用和这个有关。

这个实现是在 longobject.c 文件中(更新:链接到Python3)。我并不声称完全理解发生了什么。我觉得这里面有几个因素在起作用,它们缓存了临时引用:

print sys.getrefcount('foo1111111111111' + 'bar1111111111111') #1
print sys.getrefcount(111111111111 + 2222222222222)            #2
print sys.getrefcount('foobar333333333333333333')              #3

撰写回答