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

2024-04-19 14:58:59 发布

您现在位置:Python中文网/ 问答频道 /正文

当创建一个类时,会生成对该类的四个引用,该类从未在type.__new__的命名空间参数中传递过__classcell__,也就是一个没有任何函数需要操作码LOAD_NAME - __class__的类。我可以解释其中一个,但由于我几乎看不懂C,我只能推测其他3个。最明显的是,第一个是类在其中定义的模块的__dict__中的引用。另一个在typeobject.c的缓存中。过了一段时间,如果一个类的引用计数降到4以下,它就会被销毁,这对于函数中定义的类来说是一件好事,因为在函数执行之后,没有办法删除它。 另外,在type.mro用来生成mro的任何地方都可能有一个引用。你知道吗

最后,我猜最后一个是零参数super可以访问的地方,这就是我要了解的真正信息:为什么在类定义之外创建的函数不能与零参数super一起工作,即使它的__code__.co_names中有'__class__',而它的__closure__中有类的单元格?仍然产生RuntimeError: super(): __class__ cell not found。你知道吗

__classcell__的类(我说,因为我相信名称最终会被删除)在创建时有5个引用,比没有多了一个。由于在所有提到零参数super()__class__的函数的__closure__中包含类对象的单元格是相同的,我认为types.FunctionType.__closure__描述符使用额外的引用来生成包含这些单元格的tuple是一个很好的选择。你知道吗


Tags: 函数namenew参数定义type地方空间
1条回答
网友
1楼 · 发布于 2024-04-19 14:58:59

让我们看看^{}

>>> 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__可能不明显,但我们可以确认:)

>>> gc.get_referrers(Foo)[2] is Foo.__mro__
True

__dict____weakref__描述符管理对Foo实例的__dict____weakref__属性的访问,它们需要对Foo的引用来进行类型检查,以确保它们仅用于Foo实例。你知道吗

__mro__是Python搜索的类序列,用于解析Foo的类属性,以及解析由数据描述符管理的Foo的实例属性或实例__dict__中没有条目的实例属性。你知道吗

相关问题 更多 >