Python 来自sys.getrefcount的意外结果

Python 来自sys.getrefcount的意外结果,python,garbage-collection,Python,Garbage Collection,当我打字时: >>> astrd = 123 >>> import sys >>> sys.getrefcount(astrd) 3 >>> 我不知道哪里有astrd使用了3次?来自: 。。。返回的计数通常比您预期的高一个, 因为它包含(临时)引用作为getrefcount()的参数 其他两个引用意味着python在内部持有对对象的两个引用。也许locals()和globals()字典都算作一个引用?我想它算作对123的

当我打字时:

>>> astrd = 123
>>> import sys
>>> sys.getrefcount(astrd)
3
>>> 
我不知道哪里有
astrd
使用了3次?

来自:

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


其他两个引用意味着python在内部持有对对象的两个引用。也许locals()和globals()字典都算作一个引用?

我想它算作对123的引用,试试其他例子,比如

>>> import sys
>>> astrd = 1
>>> sys.getrefcount(astrd)
177
>>> astrd = 9802374987193847
>>> sys.getrefcount(astrd)
2
>>> 
9802374987193847的参考计数符合codeape的答案

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


顺便说一句,我得到了123以及2,也许你的设置有些不同?或者它可能与时间有关,或者与时间有关?

int是以一种特殊的方式实现的,它们是缓存和共享的,这就是为什么您得不到1的原因


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

三次引用的不是
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(以及其他)的一个实现细节。由于小整数经常被实例化,共享它们可以节省大量内存。这一点之所以可能,是因为整数首先是不可变的

对于第二个示例中的附加引用,cf..

那么,当我执行“del astrd”时,其引用计数变为0,并由gc收集?