Reputation: 15349
I understand that, in CPython 2.x and 3.x, some integers are singletons:
>>> 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
Accordingly, if I run sys.getrefcount
on an integer in the range -5 to 256, I find that a lot of my imported packages have referenced that integer:
>>> sys.getrefcount(1)
1470
I also understand that sys.getrefcount
returns 1 more than you might expect, because of its own reference to the argument:
>>> a = 257; sys.getrefcount(a)
2
What I don't get is this:
>>> sys.getrefcount(257)
3
Why 3, not 2? I could understand that I might have created a temporary variable in my own scope (count 1), and clearly sys.getrefcount
would add another reference of its own to that (count 2) but where does the third one come from, and why didn't happen in the previous example? And more importantly: are there other contexts in which this might occur, leading to possible misinterpretation of sys.getrefcount
outputs?
All of the above are replicable for me on 64-bit Python 2.7.12 and 3.5.1 by Anaconda, running on OSX, and also on a 32-bit Python 2.7.5 distribution running on Windows. However, on an older Python version (32-bit Python 2.5.4 on Windows), sys.getrefcount(257)
returns 2 which is (to me) more expected.
Upvotes: 2
Views: 278
Reputation: 1122222
You are running into an implementation detail here. The compiler can often cache immutable literal values:
>>> 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'
is the mode used by the interactive interpreter).
We see 3 references here; one from the co_consts
tuple on the code object, one on the stack (from the LOAD_CONST
instruction), and one for the sys.getrefcount()
method itself.
Upvotes: 3