-1

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

from sys import getrefcount

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

print(getrefcount(Foo))  # 5
4

1 回答 1

1

一个有趣的!!

我使用以下脚本来获取推荐人列表

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()返回的值比预期值大 1,因此它会验证 list of 的长度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
于 2019-11-22T14:42:34.520 回答