sys.getrefcount() 的返回值
为什么
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 个回答
看起来,当你把一个直接的数字作为参数传给sys.getrefcount时,实际上有3个引用:
- 一个是对象本身的引用(逻辑上的);
- 一个是临时的引用,用于传递给sys.getrefcount的对象;
- 还有一个我猜是临时的引用,给解释器用的,它把原始的数字(或者字符串,或者其他任何东西)转换成可以理解的对象。
举个例子,我们来看这个:
>>> sys.getrefcount(123456)
3
>>> a = 123456
>>> sys.getrefcount(a)
2
我不太清楚Python内部到底是怎么想的,但这确实很有趣。我只能猜测,原始的整数(引用#1)会暂时转换成一个int对象(引用#2),然后这个对象作为参数传给sys.getrefcount(引用#3)。
为了节省创建对象的时间,Python会对小字符串和整数进行缓存。
当你在交互式Python解释器中输入内容时,它会暂时保存你输入的每个字面量的引用。比如,比较一下
getrefcount('foobar')
和getrefcount('foo' + 'bar')
。在后者的情况下,解释器会分别保存'foo'
和'bar'
的引用。来自手册的说明:
返回的计数通常比你预期的要多1,因为它还包括作为参数传递给
getrefcount()
的(临时)引用。
大整数对象不会被解释器重复使用,所以你会得到两个不同的对象:
>>> 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