据我了解,在 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
输出的可能误解?
以上所有内容都可以在 OSX 上运行的 Anaconda 64 位 Python 2.7.12 和 3.5.1 上复制,也可以在 Windows 上运行的 32 位 Python 2.7.5 发行版上复制。但是,在较旧的 Python 版本(Windows 上的 32 位 Python 2.5.4)上,sys.getrefcount(257)
返回 2,这(对我来说)更符合预期。
最佳答案
您在这里遇到了实现细节。编译器通常可以缓存不可变的文字值:
>>> 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()
方法本身。
关于python - 未命名整数文字的意外引用计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41510067/