什么是 __weakrefoffset__?

What is __weakrefoffset__?

__weakrefoffset__ 属性有什么用?整数值表示什么?

>>> int.__weakrefoffset__ 
0
>>> class A: 
...     pass 
... 
>>> A.__weakrefoffset__ 
24
>>> type.__weakrefoffset__ 
368
>>> class B: 
...     __slots__ = () 
...
>>> B.__weakrefoffset__
0

似乎所有类型都有这个属性。但是 docs nor in PEP 205.

中没有提到这一点

在CPython中,像float这样的简单类型的布局是三个字段:它的类型指针,它的引用计数,它的值(这里是一个double) .对于list,该值是三个变量(指向separately-allocated数组的指针、它的容量和使用的大小)。这些类型不支持属性或弱引用保存 space.

如果 Python class 从其中之一继承,它能够支持属性是至关重要的,但没有固定的偏移量来放置 __dict__指针(不会通过将其置于未使用的大偏移量而浪费内存)。所以字典存储在有空间的地方,它的字节偏移量是recorded in the type。对于大小可变的基 classes(如 tuple,它直接包含其所有指针),特别支持将 __dict__ 指针存储在 [=29 的末尾之后=]部分(例如type("",(tuple,),{}).__dictoffset__是-8)。

弱引用的情况是 exactly analogous,只是不支持 variable-sized 的(子classes)类型。 __weakrefoffset__ 为 0(这是 C 静态变量的默认默认值)表示不支持,因为当然已知对象的类型始终位于其布局的开头。

此处PEP 205中引用:

Many built-in types will participate in the weak-reference management, and any extension type can elect to do so. The type structure will contain an additional field which provides an offset into the instance structure which contains a list of weak reference structures. If the value of the field is <= 0, the object does not participate. In this case, weakref.ref(), .setitem() and .setdefault(), and item assignment will raise TypeError. If the value of the field is > 0, a new weak reference can be generated and added to the list.

你可以在源代码中看到它是如何工作的 here

查看其他答案以了解其存在的更多原因。