В CPython макет простого типа, такого как float
, состоит из трех полей: указатель типа, счетчик ссылок и его значение (здесь double
).Для list
значением являются три переменные (указатель на отдельно выделенный массив, его емкость и используемый размер).Эти типы не поддерживают атрибуты или слабые ссылки для экономии места.
Если класс Python наследует от одного из них, очень важно, чтобы он мог поддерживать атрибуты, и при этом нет фиксированного смещения для размещенияуказатель __dict__
(без потери памяти, помещая ее в большое неиспользуемое смещение).Таким образом, словарь хранится везде, где есть место, и его смещение в байтах записывается в виде .Для базовых классов, где размер является переменным (например, tuple
, который включает в себя все его указатели напрямую), существует специальная поддержка для хранения указателя __dict__
после конца секции переменного размера ( например , type("",(tuple,),{}).__dictoffset__
- это -8).
Ситуация со слабыми ссылками в точности аналогична , за исключением того, что нет поддержки (подклассов) типов переменного размера.Значение __weakrefoffset__
, равное 0 (что по умолчанию удобно для статических переменных C), указывает на отсутствие поддержки, поскольку, конечно, тип объекта всегда находится в начале его макета.