【发布时间】:2009-04-17 09:29:39
【问题描述】:
当我输入时:
>>> astrd = 123
>>> import sys
>>> sys.getrefcount(astrd)
3
>>>
我不知道astrd 在哪里使用了 3 次?
【问题讨论】:
当我输入时:
>>> astrd = 123
>>> import sys
>>> sys.getrefcount(astrd)
3
>>>
我不知道astrd 在哪里使用了 3 次?
【问题讨论】:
被引用三次的不是astrd,而是值123。 astrd 只是(不可变)数字 123 的名称,可以多次引用。除此之外,通常共享小整数:
>>> astrd = 123
>>> sys.getrefcount(astrd)
4
>>> j = 123
>>> sys.getrefcount(astrd)
5
在第二个赋值中,没有创建新的整数,而是j 只是整数123 的新名称。
但是,给定非常大的整数,这不成立:
>>> i = 823423442583
>>> sys.getrefcount(i)
2
>>> j = 823423442583
>>> sys.getrefcount(i)
2
共享整数是 CPython(以及其他)的一个实现细节。由于小整数经常被实例化,共享它们可以节省大量内存。这是因为整数是不可变的。
有关第二个示例中的附加参考,请参阅。 codeape's answer.
【讨论】:
... 返回的计数通常比您预期的高 1, 因为它包含(临时)引用作为
getrefcount()的参数。
另外两个引用意味着 python 在内部持有两个对该对象的引用。也许 locals() 和 globals() 字典都算作一个引用?
【讨论】:
我认为它计算了对 123 的引用,请尝试其他示例,例如
>>> import sys
>>> astrd = 1
>>> sys.getrefcount(astrd)
177
>>> astrd = 9802374987193847
>>> sys.getrefcount(astrd)
2
>>>
9802374987193847 的引用计数符合 codeape 的答案。
这可能是因为数字是不可变的。例如,如果您使用一个列表,它将始终为 2(来自一个干净的提示)。
顺便说一句,我也得到 123 的 2,也许你的设置有些不同?或者可能与时间有关?
【讨论】:
ints 以一种特殊的方式实现,它们被缓存和共享,这就是为什么你没有得到 1。
和 python,使用引用计数的对象。 astrd 本身就是一个引用,因此您实际上获得了对 int '123' 的引用数。尝试使用另一种(用户定义的)类型,你会得到 1。
【讨论】: