来自sys.getrefcount的意外结果

时间:2009-04-17 09:29:39

标签: python garbage-collection

当我输入:

>>> astrd = 123
>>> import sys
>>> sys.getrefcount(astrd)
3
>>> 

我没有得到astrd使用3次的地方?

4 个答案:

答案 0 :(得分:7)

来自getrefcount docstring

  

...返回的计数通常比您预期的高一个,   因为它包含(临时)引用作为getrefcount()的参数。

另外两个引用意味着python内部持有对该对象的两个引用。也许locals()和globals()字典统计为每个参考?

答案 1 :(得分:7)

引用三次的astrd不是123,而是值astrd>>> astrd = 123 >>> sys.getrefcount(astrd) 4 >>> j = 123 >>> sys.getrefcount(astrd) 5 只是(不可变)数字123的名称,可以多次引用。除此之外,通常会共享小整数:

j

在第二个赋值中,没有创建新的整数,而123只是整数>>> i = 823423442583 >>> sys.getrefcount(i) 2 >>> j = 823423442583 >>> sys.getrefcount(i) 2 的新名称。

但是,给定非常大的整数,这不成立:

{{1}}

共享整数是CPython(以及其他)的实现细节。由于小整数经常被实例化,因此共享它们可以节省大量内存。这是因为整数首先是不可变的。

对于第二个例子中的附加参考,参见codeape's answer

答案 2 :(得分:6)

我认为它会计算对123的引用,尝试其他示例,例如

>>> import sys
>>> astrd = 1
>>> sys.getrefcount(astrd)
177
>>> astrd = 9802374987193847
>>> sys.getrefcount(astrd)
2
>>> 

9802374987193847的引用数量符合代码的答案。

这可能是因为数字是不可变的。例如,如果您使用列表,它将始终为2(来自干净的提示)。

不过,顺便提一下,123也是2,也许你的设置有些不同?或者它可能与时间有关?

答案 3 :(得分:5)

int以特殊方式实现,它们被缓存和共享,这就是为什么你没有得到1。

和python一样,使用引用计数对象。 astrd本身就是一个引用,所以你实际上得到了int'123'的引用数。尝试使用其他(用户定义的)类型,您将获得1。

相关问题