Что такое __weakrefoffset__? - PullRequest
       23

Что такое __weakrefoffset__?

2 голосов
/ 17 мая 2019

Для чего нужен атрибут __weakrefoffset__? Что означает целочисленное значение?

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

Кажется, у всех типов есть этот атрибут. Но об этом нет упоминания ни в документах , ни в PEP 205 .

Ответы [ 2 ]

2 голосов
/ 17 мая 2019

В CPython макет простого типа, такого как float, состоит из трех полей: указатель типа, счетчик ссылок и его значение (здесь double).Для list значением являются три переменные (указатель на отдельно выделенный массив, его емкость и используемый размер).Эти типы не поддерживают атрибуты или слабые ссылки для экономии места.

Если класс Python наследует от одного из них, очень важно, чтобы он мог поддерживать атрибуты, и при этом нет фиксированного смещения для размещенияуказатель __dict__ (без потери памяти, помещая ее в большое неиспользуемое смещение).Таким образом, словарь хранится везде, где есть место, и его смещение в байтах записывается в виде .Для базовых классов, где размер является переменным (например, tuple, который включает в себя все его указатели напрямую), существует специальная поддержка для хранения указателя __dict__ после конца секции переменного размера ( например , type("",(tuple,),{}).__dictoffset__ - это -8).

Ситуация со слабыми ссылками в точности аналогична , за исключением того, что нет поддержки (подклассов) типов переменного размера.Значение __weakrefoffset__, равное 0 (что по умолчанию удобно для статических переменных C), указывает на отсутствие поддержки, поскольку, конечно, тип объекта всегда находится в начале его макета.

0 голосов
/ 17 мая 2019

Ссылка на PEP 205 здесь:

Многие встроенные типы будут участвовать в управлении слабыми ссылками, и любой тип расширения может выбрать это. Структура типа будет содержать дополнительное поле, которое обеспечивает смещение в структуре экземпляра, которая содержит список слабых ссылочных структур. Если значение поля <= 0, объект не участвует. В этом случае weakref.ref (),. <strong>setitem () и .setdefault (), а назначение элемента вызовет TypeError. Если значение поля> 0, можно создать новую слабую ссылку и добавить ее в список.

И вы можете точно увидеть, как это работает в исходном коде здесь .

Проверьте другой ответ, чтобы узнать, почему он существует.

...