当创建一个从未在__classcell__
的名称空间参数中传递type.__new__
的类时,会产生对类的四个引用,也就是没有需要操作码的函数的类{{ 1}}。我可以解释一个,但因为我几乎无法读取CI只能推测其他3.最明显的是,第一个是类定义的模块的LOAD_NAME - __class__
中的引用。另一个我认为一个是在__dict__
的缓存中。如果一个类的引用计数低于4,它会被销毁,这对函数中定义的类来说是一件好事,因为在执行函数后无法删除它。
在typeobject.c
用于生成mros的任何内容中也许都有一个引用。
最后,我猜测最后是零参数type.mro
可以访问的地方,这就是我所追求的真实信息:为什么在类定义之外创建的函数不能使用零参数{{ 1}},即使它的super
中有super
,而'__class__'
中有一个类的单元格?仍然会产生__code__.co_names
。
具有__closure__
的类(我说有因为我相信该名称最终被删除)在创建时有5个引用,而不是。在所有提及零参数RuntimeError: super(): __class__ cell not found
或__classcell__
的函数的__closure__
中看到包含类对象的单元格是相同的,我认为这是一个很好的选择,{super()
使用了额外的引用{1}}描述符,用于生成包含单元格的__class__
。
答案 0 :(得分:2)
让我们看看gc.get_referrers
:
>>> import gc
>>> import pprint
>>> class Foo: pass
...
>>> pprint.pprint(gc.get_referrers(Foo))
[<attribute '__dict__' of 'Foo' objects>,
<attribute '__weakref__' of 'Foo' objects>,
(<class '__main__.Foo'>, <class 'object'>),
{'Foo': <class '__main__.Foo'>,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__cached__': None,
'__doc__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7ff284402da0>,
'__name__': '__main__',
'__package__': None,
'__spec__': None,
'gc': <module 'gc' (built-in)>,
'pprint': <module 'pprint' from '/usr/local/lib/python3.6/pprint.py'>}]
我们可以在此列表中看到您遗失的3个引用来自__dict__
和__weakref__
descriptors以及类__mro__
。 (可能不太明显第三个条目是__mro__
,但我们可以确认:)
>>> gc.get_referrers(Foo)[2] is Foo.__mro__
True
__dict__
和__weakref__
描述符管理对__dict__
个实例的__weakref__
和Foo
属性的访问权限,并且需要对Foo
的引用}用于类型检查,以确保它们仅用于Foo
个实例。
__mro__
是Python搜索以解析Foo
的类属性的类序列,并解析由数据描述符管理的Foo
的实例属性; t在实例__dict__
中有一个条目。