首先:这都是cpython特有的。弱引用在不同的Python实现上的工作方式有所不同。
大多数内置类型不支持弱引用,因为Python的弱引用机制为支持弱引用的每个对象增加了一些开销,并且Python开发人员团队决定他们不希望大多数内置类型来承担这种开销。这种开销体现的最简单的方式是,任何具有弱引用支持的对象都需要一个空间来为弱引用管理提供额外的指针,并且大多数内置对象都不为该指针保留空间。
试图用弱参考支持来编译所有类型的完整列表与尝试编译所有有红头发的人的完整列表一样富有成果。如果要确定某个类型是否具有弱引用支持,则可以检查其__weakrefoffset__
,对于具有弱引用支持的类型,该值非零:
>>> int.__weakrefoffset__
0
>>> type.__weakrefoffset__
368
>>> tuple.__weakrefoffset__
0
>>> class Foo(object):
... pass
...
>>> class Bar(tuple):
... pass
...
>>> Foo.__weakrefoffset__
24
>>> Bar.__weakrefoffset__
0
类型的值__weakrefoffset__
是从实例开始到弱引用指针的字节偏移量,如果实例没有弱引用指针,则为0。它对应tp_weaklistoffset
于C级别的struct类型。截至撰写本文时,__weakrefoffset__
尚未完全记录,但tp_weaklistoffset
已 记录了,因为在C中实现扩展类型的人们需要了解它。