据我所知,在CPython 2.x和3.x中,有些整数是单例:
>>> a = 256; a is 256 # or any integer from -5 to 256
True
>>> a = 257; a is 257 # or any other integer outside the magic range
False
因此,如果我在-5到256范围内的整数上运行sys.getrefcount
,我发现很多导入的包都引用了这个整数:
>>> sys.getrefcount(1)
1470
我也理解sys.getrefcount
比你预期的更多返回1,因为它的自己的引用了参数:
>>> a = 257; sys.getrefcount(a)
2
我没有得到的是:
>>> sys.getrefcount(257)
3
为什么3,而不是2?我可以理解我可能已经在我自己的范围内创建了一个临时变量(计数1),并且显然sys.getrefcount
会添加另一个自己的引用(计数2)但是第三个来自哪里,并且为什么在前面的例子中没有发生?更重要的是:是否存在可能发生这种情况的其他情况,导致可能误解sys.getrefcount
输出?
以上所有内容都可以在64位Python 2.7.12和3.5.1上由Anaconda复制,在OSX上运行,也可以在Windows上运行的32位Python 2.7.5发行版上复制。但是,在较旧的Python版本(Windows上的32位Python 2.5.4)上,sys.getrefcount(257)
返回2,这对我来说是更多的预期。
答案 0 :(得分:3)
您在此处遇到了一个实施细节。编译器通常可以缓存不可变的文字值:
>>> import dis
>>> compile("sys.getrefcount(257)", '', 'single').co_consts
(257, None)
>>> dis.dis(compile("sys.getrefcount(257)", '', 'single'))
1 0 LOAD_NAME 0 (sys)
2 LOAD_ATTR 1 (getrefcount)
4 LOAD_CONST 0 (257)
6 CALL_FUNCTION 1
8 PRINT_EXPR
10 LOAD_CONST 1 (None)
12 RETURN_VALUE
('single'
是交互式解释器使用的模式。)
我们在这里看到3个引用;一个来自代码对象上的co_consts
元组,一个位于堆栈上(来自LOAD_CONST
指令),另一个来自sys.getrefcount()
方法本身。