You could use gc.get_referrers()
to see what the referring objects are to help with your shock:
I elided True
, because it's understandably used in a bunch of places.
The refs N
counts occasionally differ from the count gc.get_referrers()
since getrefcount()
only looks at the refcount for an object, and that can change within a CPython function's (such as getrefcount()
itself) execution.
for obj in (integer_1, float_1, string_1, LIST_1, TUPLE_1, SET_1, DICTIONARY_1):
print(repr(obj), "of type", type(obj), "refs", sys.getrefcount(obj))
for ref in gc.get_referrers(obj):
print(" ", type(ref), str(ref)[:70])
On my interpreter this outputs something like this (#
lines are my commentary).
9 of type <class 'int'> refs 26
# module internals for `__main__`
<class 'list'> [b'import', b'gc', 'gc', b'', 'gc', b'import', b'sys', 'sys', b'', 'sy
<class 'tuple'> (0, None, 9, 3.14, 'Some String', True, 1, 3, (1, 3), '1', '3', 'of ty
# module internals for some other module
<class 'tuple'> (9, 3.14, 'Some String', [1, 3], (1, 3), {1, 3}, {1: '1', 3: '3'})
<class 'tuple'> (None, ('to',), <code object print_ at 0x10906f680, file "/usr/local/C
# a tuple from some other module
<class 'tuple'> (LITERAL, 9)
# module globals dicts for various modules
<class 'dict'> {'__name__': '_locale', '__doc__': 'Support for POSIX locales.', '__pa
<class 'dict'> {'__name__': 'tokenize', '__doc__': 'Tokenization help for Python prog
<class 'dict'> {'__name__': 'token', '__doc__': 'Token constants.', '__package__': ''
<class 'dict'> {'__new__': <built-in method __new__ of type object at 0x108d7f748>, '
<class 'dict'> {'__new__': <built-in method __new__ of type object at 0x108d81938>, '
<class 'dict'> {'__name__': '_signal', '__doc__': 'This module provides mechanisms to
<class 'dict'> {'__name__': '__main__', '__doc__': None, '__package__': None, '__load
<class 'dict'> {'__name__': 'stat', '__doc__': 'Constants/functions for interpreting
<class 'dict'> {'__name__': '_stat', '__doc__': 'S_IFMT_: file type bits\nS_IFDIR: di
3.14 of type <class 'float'> refs 6
# module internals and globals dict for `__main__`
<class 'list'> [b'import', b'gc', 'gc', b'', 'gc', b'import', b'sys', 'sys', b'', 'sy
<class 'tuple'> (0, None, 9, 3.14, 'Some String', True, 1, 3, (1, 3), '1', '3', 'of ty
<class 'tuple'> (9, 3.14, 'Some String', [1, 3], (1, 3), {1, 3}, {1: '1', 3: '3'})
<class 'dict'> {'__name__': '__main__', '__doc__': None, '__package__': None, '__load
'Some String' of type <class 'str'> refs 6
# module internals and globals dict for `__main__`
<class 'list'> [b'import', b'gc', 'gc', b'', 'gc', b'import', b'sys', 'sys', b'', 'sy
<class 'tuple'> (0, None, 9, 3.14, 'Some String', True, 1, 3, (1, 3), '1', '3', 'of ty
<class 'tuple'> (9, 3.14, 'Some String', [1, 3], (1, 3), {1, 3}, {1: '1', 3: '3'})
<class 'dict'> {'__name__': '__main__', '__doc__': None, '__package__': None, '__load
[1, 3] of type <class 'list'> refs 4
# module internals and globals dict for `__main__`
<class 'tuple'> (9, 3.14, 'Some String', [1, 3], (1, 3), {1, 3}, {1: '1', 3: '3'})
<class 'dict'> {'__name__': '__main__', '__doc__': None, '__package__': None, '__load
(1, 3) of type <class 'tuple'> refs 6
# module internals and globals dict for `__main__`
<class 'list'> [b'import', b'gc', 'gc', b'', 'gc', b'import', b'sys', 'sys', b'', 'sy
<class 'tuple'> (0, None, 9, 3.14, 'Some String', True, 1, 3, (1, 3), '1', '3', 'of ty
<class 'tuple'> (9, 3.14, 'Some String', [1, 3], (1, 3), {1, 3}, {1: '1', 3: '3'})
<class 'dict'> {'__name__': '__main__', '__doc__': None, '__package__': None, '__load
{1, 3} of type <class 'set'> refs 4
# module internals and globals dict for `__main__`
<class 'tuple'> (9, 3.14, 'Some String', [1, 3], (1, 3), {1, 3}, {1: '1', 3: '3'})
<class 'dict'> {'__name__': '__main__', '__doc__': None, '__package__': None, '__load
{1: '1', 3: '3'} of type <class 'dict'> refs 4
# module internals and globals dict for `__main__`
<class 'tuple'> (9, 3.14, 'Some String', [1, 3], (1, 3), {1, 3}, {1: '1', 3: '3'})
<class 'dict'> {'__name__': '__main__', '__doc__': None, '__package__': None, '__load
This also ties into the CPython small integer cache; certain small integers (e.g. that 9) are always the same object for performance reasons, while arbitrary integers are likely allocated separately:
923852 of type <class 'int'> refs 6
<class 'list'> [b'import', b'gc', 'gc', b'', 'gc', b'import', b'sys', 'sys', b'', 'sy
<class 'tuple'> (0, None, 9, 923852, 3.14, 'Some String', True, 1, 3, (1, 3), '1', '3'
<class 'tuple'> (923852,)
<class 'dict'> {'__name__': '__main__', '__doc__': None, '__package__': None, '__load