在类定义完成后,类对象的所有引用都位于何处?

时间:2017-11-29 22:27:43

标签: python python-3.x

当创建一个从未在__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__

1 个答案:

答案 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__中有一个条目。