我在Windows上用Python 3.7玩sys.getrefcount
。我尝试了以下方法:
>>> import sys
>>> x = "this is an arbitrary string"
>>> sys.getrefcount(x)
2
我知道其中一个引用是
x
,另一个是sys.getrefcount
内部使用的参数。不管x
初始化到什么类型,这似乎都可以工作。然而,我注意到一些奇怪的行为,当我没有分配之前,我通过:>>> import sys
>>> sys.getrefcount("arbitrary string")
2
>>> sys.getrefcount(1122334455)
2
>>> sys.getrefcount(1122334455+1)
2
>>> sys.getrefcount(frozenset())
2
>>> sys.getrefcount(set())
1
>>> sys.getrefcount(object())
1
>>> sys.getrefcount([])
1
>>> sys.getrefcount(lambda x: x)
1
>>> sys.getrefcount(range(1122334455))
1
>>> sys.getrefcount(dict())
1
>>> sys.getrefcount(())
8341
>>> sys.getrefcount(tuple())
8340
>>> sys.getrefcount(list("arbitrary string"))
1
>>> sys.getrefcount(tuple("arbitrary string"))
1
>>> sys.getrefcount(("a", "r", "b", "i", "t", "r", "a", "r", "y", " ", "s", "t", "r", "i", "n", "g"))
2
这是怎么回事?似乎不可变类型有两个引用,但可变类型只有一个?为什么有些对象在被传递之前就被赋值了,而另一些对象却只有一个引用作为参数?
这和拘留有关系吗?
编辑:一个更直接的问题:为什么选择不可变类型如
str
在构造时有引用,而不可变类型如int
没有引用?我孤立地理解,为什么您可能会选择保留这个全局范围参考或不全面,但为什么存在差异? 最佳答案
一个有趣的问题,这里有一个有趣的read。
你应该试试getrefcount(2)
,对我来说它返回了93,这意味着CPython为相同的内存地址保留了93个引用,保留了数字2,所以它不必再次分配它,因为它是不可变的,所以这样做是完全可以的。
现在让我们尝试两种不同的方法:
# first
getrefcount(set()) # returns 1
# second
s = set()
getrefcount(s) # returns 2
因为它是可变类型,所以当您创建可变类型(
set()
)时,它的行为是不同的,它将在内存中分配它,并且只有对它的一个引用,该引用将在此行结束后立即删除。但是在第二步,我们定义变量并分配它,当计算引用时,我们有一个被s
使用,另一个在函数getrefcount
中使用。而在Pythontuples are immutable中,这就是它返回大量数据的原因,CPython保留了大量对空元组的引用。
关于python - 哪些类型的Python对象是使用引用初始化的,哪些不是?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56487409/