Python 3.8 sys.getrefcount() returns 5 第一次调用

Python 3.8 sys.getrefcount() returns 5 on first call

为什么打印 5?使用 python 3.8。我理解 sys.getrefcount() returns 值 1 大于预期,但是 5 ?

from sys import getrefcount

class Foo():
    def __del__(self):
        print('__del__() called')

print(getrefcount(Foo))  # 5

有趣的一个!!

我使用以下脚本获取了 referrers

的列表
import gc
import pprint
import sys


class Example:
    def __del__(self):
        print("__del__() is called")


if __name__ == "__main__":
    reference_count = sys.getrefcount(Example)
    print(f"Reference count is {reference_count}")

    pretty = pprint.PrettyPrinter(indent=4)

    for referrer in gc.get_referrers(Example):
        if isinstance(referrer, dict):
            pretty.pprint(referrer)
            continue
        pretty.pprint(referrer)

这是输出

➜ python3.8 reference_count.py
Reference count is 5
<attribute '__dict__' of 'Example' objects>
<attribute '__weakref__' of 'Example' objects>
(<class '__main__.Example'>, <class 'object'>)
{   'Example': <class '__main__.Example'>,
    '__annotations__': {},
    '__builtins__': <module 'builtins' (built-in)>,
    '__cached__': None,
    '__doc__': None,
    '__file__': 'temp.py',
    '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x1006d4550>,
    '__name__': '__main__',
    '__package__': None,
    '__spec__': None,
    'gc': <module 'gc' (built-in)>,
    'pprint': <module 'pprint' from '/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pprint.py'>,
    'pretty': <pprint.PrettyPrinter object at 0x1006e29d0>,
    'reference_count': 4,
    'referrer': <Recursion on dict with id=4301742016>,
    'sys': <module 'sys' (built-in)>}

因为 sys.getrefcount() returns 比预期值大 1,它验证 referrers.

列表的长度

更正

问题中要注意的一点是我们还没有真正调用 Example object 的引用计数,因此从未调用过 __del__,这是一个稍微不同的例子。

...
    reference_count = sys.getrefcount(Example())
...
    for referrer in gc.get_referrers(Example()):
...

这是输出

__del__() is called
Reference count is 1
__del__() is called