Документация Python неофициальный перевод

typeobj.md

787 строк · 85.3 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.2/c-api/typeobj.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Объекты типов89Пожалуй, одна из самых важных структур объектной системы Python – это структура, определяющая новый тип: структура [`PyTypeObject`](https://python-all.ru/3.2/c-api/type.html#PyTypeObject). С объектами типов можно работать через любую из функций `PyObject_*()` или `PyType_*()`, но они не представляют большого интереса для большинства приложений Python. Эти объекты лежат в основе поведения объектов, поэтому они очень важны как для самого интерпретатора, так и для любых расширяющих модулей, реализующих новые типы.1011Объекты типа довольно велики по сравнению с большинством стандартных типов. Причина такого размера в том, что каждый объект типа хранит большое количество значений, в основном указателей на функции C, каждый из которых реализует небольшую часть функциональности типа. Поля объекта типа подробно рассматриваются в этом разделе. Поля будут описаны в порядке их появления в структуре.1213Определения типов: unaryfunc, binaryfunc, ternaryfunc, inquiry, intargfunc, intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, reprfunc, hashfunc1415Определение структуры [`PyTypeObject`](https://python-all.ru/3.2/c-api/type.html#PyTypeObject) можно найти в файле `Include/object.h`. Для удобства здесь повторяется это определение:1617```c18typedef struct _typeobject {19    PyObject_VAR_HEAD20    char *tp_name; /* Для вывода в формате "<module>.<name>" */21    int tp_basicsize, tp_itemsize; /* Для выделения памяти */2223    /* Методы для реализации стандартных операций */2425    destructor tp_dealloc;26    printfunc tp_print;27    getattrfunc tp_getattr;28    setattrfunc tp_setattr;29    void *tp_reserved;30    reprfunc tp_repr;3132    /* Наборы методов для стандартных классов */3334    PyNumberMethods *tp_as_number;35    PySequenceMethods *tp_as_sequence;36    PyMappingMethods *tp_as_mapping;3738    /* Дополнительные стандартные операции (здесь для двоичной совместимости) */3940    hashfunc tp_hash;41    ternaryfunc tp_call;42    reprfunc tp_str;43    getattrofunc tp_getattro;44    setattrofunc tp_setattro;4546    /* Функции для доступа к объекту как к буферу ввода/вывода */47    PyBufferProcs *tp_as_buffer;4849    /* Флаги для определения наличия опциональных/расширенных возможностей */50    long tp_flags;5152    char *tp_doc; /* Строка документации */5354    /* вызов функции для всех доступных объектов */55    traverseproc tp_traverse;5657    /* удаление ссылок на содержащиеся объекты */58    inquiry tp_clear;5960    /* расширенные сравнения */61    richcmpfunc tp_richcompare;6263    /* включение слабых ссылок */64    long tp_weaklistoffset;6566    /* Итераторы */67    getiterfunc tp_iter;68    iternextfunc tp_iternext;6970    /* Дескриптор атрибутов и механизмы подклассов */71    struct PyMethodDef *tp_methods;72    struct PyMemberDef *tp_members;73    struct PyGetSetDef *tp_getset;74    struct _typeobject *tp_base;75    PyObject *tp_dict;76    descrgetfunc tp_descr_get;77    descrsetfunc tp_descr_set;78    long tp_dictoffset;79    initproc tp_init;80    allocfunc tp_alloc;81    newfunc tp_new;82    freefunc tp_free; /* Низкоуровневая процедура освобождения памяти */83    inquiry tp_is_gc; /* Для PyObject_IS_GC */84    PyObject *tp_bases;85    PyObject *tp_mro; /* порядок разрешения методов */86    PyObject *tp_cache;87    PyObject *tp_subclasses;88    PyObject *tp_weaklist;8990} PyTypeObject;91```9293Структура объекта типа расширяет структуру [`PyVarObject`](https://python-all.ru/3.2/c-api/structures.html#PyVarObject). Поле `ob_size` используется для динамических типов (создаваемых `type_new()`, обычно вызываемой из объявления класса). Обратите внимание, что [`PyType_Type`](https://python-all.ru/3.2/c-api/type.html#PyType_Type) (метатип) инициализирует `tp_itemsize`, а это значит, что его экземпляры (т.е. объекты типа) *должны* иметь поле `ob_size`.9495**[PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject)\* `PyObject._ob_next`**9697**[PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject)\* `PyObject._ob_prev`**9899Эти поля присутствуют только тогда, когда определён макрос `Py_TRACE_REFS`. Их инициализацию значением *NULL* берёт на себя макрос `PyObject_HEAD_INIT`. Для статически выделенных объектов эти поля всегда остаются *NULL*. Для динамически выделенных объектов эти два поля используются для включения объекта в двусвязный список *всех* живых объектов в куче. Это может использоваться для различных целей отладки; в настоящее время единственное применение – вывод объектов, которые всё ещё живы в конце выполнения, когда установлена переменная окружения [`PYTHONDUMPREFS`](https://python-all.ru/3.2/using/cmdline.html#envvar-PYTHONDUMPREFS).100101Эти поля не наследуются подтипами.102103**Py\_ssize\_t `PyObject.ob_refcnt`**104105Это счётчик ссылок объекта типа, инициализированный значением `1` макросом `PyObject_HEAD_INIT`. Обратите внимание, что для статически выделенных объектов типов экземпляры типа (объекты, у которых `ob_type` указывает обратно на тип) *не* считаются ссылками. Но для динамически выделенных объектов типов экземпляры *всё же* считаются ссылками.106107Это поле не наследуется подтипами.108109**[PyTypeObject](https://python-all.ru/3.2/c-api/type.html#PyTypeObject)\* `PyObject.ob_type`**110111Это тип типа, иными словами, его метатип. Он инициализируется аргументом макроса `PyObject_HEAD_INIT`, и его значением обычно должно быть `&PyType_Type`. Однако для динамически загружаемых модулей расширения, которые должны быть работоспособны в Windows (как минимум), компилятор сообщает, что это недопустимый инициализатор. Поэтому принято передавать *NULL* макросу `PyObject_HEAD_INIT` и инициализировать это поле явно в начале функции инициализации модуля, прежде чем делать что-либо ещё. Обычно это делается так:112113```c114Foo_Type.ob_type = &PyType_Type;115```116117Это должно быть сделано до создания любых экземпляров типа. [`PyType_Ready()`](https://python-all.ru/3.2/c-api/type.html#PyType_Ready) проверяет, является ли `ob_type` значением *NULL*, и если это так, инициализирует его полем `ob_type` базового класса. [`PyType_Ready()`](https://python-all.ru/3.2/c-api/type.html#PyType_Ready) не изменит это поле, если оно не равно нулю.118119Это поле наследуется подтипами.120121**Py\_ssize\_t `PyVarObject.ob_size`**122123Для статически выделенных объектов-типов это поле должно быть инициализировано нулём. Для динамически выделенных объектов-типов это поле имеет особый внутренний смысл.124125Это поле не наследуется подтипами.126127**char\* `PyTypeObject.tp_name`**128129Указатель на строку, завершающуюся нулевым символом, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов это должно быть просто имя типа. Если модуль является подмодулем пакета, полное имя пакета входит в полное имя модуля. Например, тип с именем `T`, определённый в модуле `M` в подпакете `Q` пакета `P`, должен иметь инициализатор `tp_name` `"P.Q.M.T"`.130131Для динамически выделенных объектов типов это должно быть просто имя типа, а имя модуля должно явно храниться в словаре типа как значение ключа `'__module__'`.132133Для статически размещённых объектов типов поле tp\_name должно содержать точку. Всё, что находится перед последней точкой, становится доступным как атрибут `__module__`, а всё, что после последней точки, – как атрибут `__name__`.134135Если точка отсутствует, всё поле `tp_name` становится доступным как атрибут `__name__`, а атрибут `__module__` не определён (если только он не задан явно в словаре, как объяснено выше). Это означает, что ваш тип невозможно будет сериализовать с помощью pickle.136137Это поле не наследуется подтипами.138139**Py\_ssize\_t `PyTypeObject.tp_basicsize`**140141**Py\_ssize\_t `PyTypeObject.tp_itemsize`**142143Эти поля позволяют вычислить размер экземпляров типа в байтах.144145Существует два вида типов: типы с экземплярами фиксированной длины имеют нулевое поле `tp_itemsize`, типы с экземплярами переменной длины – ненулевое поле `tp_itemsize`. Для типа с экземплярами фиксированной длины все экземпляры имеют одинаковый размер, указанный в `tp_basicsize`.146147Для типа с экземплярами переменной длины экземпляры должны иметь поле `ob_size`, а размер экземпляра равен `tp_basicsize` плюс N, умноженное на `tp_itemsize`, где N – это «длина» объекта. Значение N обычно хранится в поле `ob_size` экземпляра. Есть исключения: например, целые числа используют отрицательное `ob_size` для обозначения отрицательного числа, и тогда N равно `abs(ob_size)`. Кроме того, наличие поля `ob_size` в структуре экземпляра не означает, что структура экземпляра имеет переменную длину (например, структура типа списка имеет экземпляры фиксированной длины, но эти экземпляры имеют значащее поле `ob_size`).148149Базовый размер включает поля в экземпляре, объявленные макросом [`PyObject_HEAD`](https://python-all.ru/3.2/c-api/structures.html#PyObject_HEAD) или [`PyObject_VAR_HEAD`](https://python-all.ru/3.2/c-api/structures.html#PyObject_VAR_HEAD) (в зависимости от того, какой используется для объявления структуры экземпляра), и в свою очередь включает поля `_ob_prev` и `_ob_next`, если они присутствуют. Это означает, что единственный правильный способ получить инициализатор для `tp_basicsize` – использовать оператор `sizeof` для структуры, используемой для объявления размещения экземпляра. Базовый размер не включает размер заголовка GC.150151Эти поля наследуются подтипами отдельно. Если базовый тип имеет ненулевое `tp_itemsize`, как правило, небезопасно устанавливать `tp_itemsize` в другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).152153Замечание о выравнивании: если элементы переменной длины требуют особого выравнивания, это должно быть обеспечено значением `tp_basicsize`. Пример: предположим, тип реализует массив `double`. `tp_itemsize` равно `sizeof(double)`. Программист должен гарантировать, что `tp_basicsize` кратно `sizeof(double)` (при условии, что это требование выравнивания для `double`).154155**destructor `PyTypeObject.tp_dealloc`**156157Указатель на функцию-деструктор экземпляра. Эта функция должна быть определена, если только тип не гарантирует, что его экземпляры никогда не будут освобождены (как в случае с синглтонами `None` и `Ellipsis`).158159Функция-деструктор вызывается макросами [`Py_DECREF()`](https://python-all.ru/3.2/c-api/refcounting.html#Py_DECREF) и [`Py_XDECREF()`](https://python-all.ru/3.2/c-api/refcounting.html#Py_XDECREF), когда счётчик ссылок становится нулевым. В этот момент экземпляр всё ещё существует, но на него нет ссылок. Функция-деструктор должна освободить все ссылки, которыми владеет экземпляр, освободить все буферы памяти, принадлежащие экземпляру (используя функцию освобождения, соответствующую функции выделения, которая использовалась для выделения буфера), и, наконец, в качестве последнего действия вызвать функцию `tp_free` типа. Если тип не является подтипизируемым (не имеет установленного бита флага [`Py_TPFLAGS_BASETYPE`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_BASETYPE)), допустимо вызывать освободитель объекта напрямую, а не через `tp_free`. Освободитель объекта должен быть тем же, который использовался для выделения экземпляра; обычно это [`PyObject_Del()`](https://python-all.ru/3.2/c-api/allocation.html#PyObject_Del), если экземпляр был выделен с помощью [`PyObject_New()`](https://python-all.ru/3.2/c-api/allocation.html#PyObject_New) или `PyObject_VarNew()`, или [`PyObject_GC_Del()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_Del), если экземпляр был выделен с помощью [`PyObject_GC_New()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_New) или [`PyObject_GC_NewVar()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_NewVar).160161Это поле наследуется подтипами.162163**printfunc `PyTypeObject.tp_print`**164165Необязательный указатель на функцию печати экземпляра.166167Функция печати вызывается только при выводе экземпляра в *реальный* файл; при выводе в псевдофайл (например, экземпляр `StringIO`) для преобразования в строку используется функция `tp_repr` или `tp_str` экземпляра. Эти функции также вызываются, когда поле `tp_print` типа равно *NULL*. Тип никогда не должен реализовывать `tp_print` так, чтобы результат отличался от вывода `tp_repr` или `tp_str`.168169Функция печати вызывается с той же сигнатурой, что и [`PyObject_Print()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Print): `int tp_print(PyObject *self, FILE *file, int flags)`. Аргумент *self* – это экземпляр, который нужно напечатать. Аргумент *file* – это файл stdio, в который выполняется печать. Аргумент *flags* состоит из битовых флагов. Единственный флаг, определённый в настоящее время – `Py_PRINT_RAW`. Когда бит флага `Py_PRINT_RAW` установлен, экземпляр должен печататься так же, как его форматировала бы `tp_str`; когда бит `Py_PRINT_RAW` сброшен, экземпляр должен печататься так же, как его форматировала бы `tp_repr`. Функция должна возвращать `-1` и устанавливать условие исключения, если во время сравнения произошла ошибка.170171Возможно, поле `tp_print` будет объявлено устаревшим. В любом случае рекомендуется не определять `tp_print`, а вместо этого полагаться на `tp_repr` и `tp_str` для печати.172173Это поле наследуется подтипами.174175**getattrfunc `PyTypeObject.tp_getattr`**176177Необязательный указатель на функцию получения строки атрибута.178179Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция `tp_getattro`, но принимает C-строку вместо строкового объекта Python для указания имени атрибута. Сигнатура такая же, как у [`PyObject_GetAttrString()`](https://python-all.ru/3.2/c-api/object.html#PyObject_GetAttrString).180181Это поле наследуется подтипами вместе с `tp_getattro`: подтип наследует как `tp_getattr`, так и `tp_getattro` от своего базового типа, если оба поля `tp_getattr` и `tp_getattro` подтипа равны *NULL*.182183**setattrfunc `PyTypeObject.tp_setattr`**184185Необязательный указатель на функцию установки строкового атрибута.186187Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция `tp_setattro`, но принимает C-строку вместо строкового объекта Python для указания имени атрибута. Сигнатура такая же, как у [`PyObject_SetAttrString()`](https://python-all.ru/3.2/c-api/object.html#PyObject_SetAttrString).188189Это поле наследуется подтипами вместе с `tp_setattro`: подтип наследует как `tp_setattr`, так и `tp_setattro` от своего базового типа, если оба поля `tp_setattr` и `tp_setattro` подтипа равны *NULL*.190191**void\* `PyTypeObject.tp_reserved`**192193Зарезервированный слот, ранее известный как tp\_compare.194195**reprfunc `PyTypeObject.tp_repr`**196197Необязательный указатель на функцию, реализующую встроенную функцию [`repr()`](https://python-all.ru/3.2/library/functions.html#repr).198199Сигнатура такая же, как у [`PyObject_Repr()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Repr); она должна возвращать строку или объект Unicode. В идеале эта функция должна возвращать строку, которая при передаче в [`eval()`](https://python-all.ru/3.2/library/functions.html#eval) в подходящем окружении возвращает объект с тем же значением. Если это невозможно, она должна возвращать строку, начинающуюся с `'<'` и заканчивающуюся `'>'`, по которой можно определить как тип, так и значение объекта.200201Если это поле не задано, возвращается строка вида `<%s object at %p>`, где `%s` заменяется на имя типа, а `%p` – на адрес памяти объекта.202203Это поле наследуется подтипами.204205**[PyNumberMethods](https://python-all.ru/3.2/c-api/typeobj.html#PyNumberMethods)\* `tp_as_number`**206207Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих числовой протокол. Эти поля описаны в [*Структуры числовых объектов*](https://python-all.ru/3.2/c-api/typeobj.html#number-structs).208209Поле `tp_as_number` не наследуется, но содержащиеся в нем поля наследуются по отдельности.210211**[PySequenceMethods](https://python-all.ru/3.2/c-api/typeobj.html#PySequenceMethods)\* `tp_as_sequence`**212213Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол последовательности. Эти поля описаны в [*Структуры объектов-последовательностей*](https://python-all.ru/3.2/c-api/typeobj.html#sequence-structs).214215Поле `tp_as_sequence` не наследуется, но содержащиеся в нем поля наследуются по отдельности.216217**[PyMappingMethods](https://python-all.ru/3.2/c-api/typeobj.html#PyMappingMethods)\* `tp_as_mapping`**218219Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол отображения. Эти поля описаны в [*Структуры объектов-отображений*](https://python-all.ru/3.2/c-api/typeobj.html#mapping-structs).220221Поле `tp_as_mapping` не наследуется, но содержащиеся в нем поля наследуются по отдельности.222223**hashfunc `PyTypeObject.tp_hash`**224225Необязательный указатель на функцию, реализующую встроенную функцию [`hash()`](https://python-all.ru/3.2/library/functions.html#hash).226227Сигнатура такая же, как у [`PyObject_Hash()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Hash); она должна возвращать значение типа Py\_hash\_t. Значение `-1` не должно возвращаться как обычное возвращаемое значение; при возникновении ошибки во время вычисления хеша функция должна установить исключение и вернуть `-1`.228229Это поле может быть явно установлено в [`PyObject_HashNotImplemented()`](https://python-all.ru/3.2/c-api/object.html#PyObject_HashNotImplemented) для блокировки наследования метода хеширования от родительского типа. Это интерпретируется как эквивалент `__hash__ = None` на уровне Python, в результате чего `isinstance(o, collections.Hashable)` корректно возвращает `False`. Обратите внимание, что верно и обратное: установка `__hash__ = None` в классе на уровне Python приведет к тому, что слот `tp_hash` будет установлен в [`PyObject_HashNotImplemented()`](https://python-all.ru/3.2/c-api/object.html#PyObject_HashNotImplemented).230231Если это поле не установлено, попытка получить хеш объекта вызывает [`TypeError`](https://python-all.ru/3.2/library/exceptions.html#TypeError).232233Это поле наследуется подтипами вместе с `tp_richcompare`: подтип наследует оба поля: `tp_richcompare` и `tp_hash`, когда оба поля `tp_richcompare` и `tp_hash` подтипа равны *NULL*.234235**ternaryfunc `PyTypeObject.tp_call`**236237Необязательный указатель на функцию, реализующую вызов объекта. Он должен быть *NULL*, если объект не является вызываемым. Сигнатура такая же, как у [`PyObject_Call()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Call).238239Это поле наследуется подтипами.240241**reprfunc `PyTypeObject.tp_str`**242243Необязательный указатель на функцию, реализующую встроенную операцию [`str()`](https://python-all.ru/3.2/library/functions.html#str). (Обратите внимание, что [`str`](https://python-all.ru/3.2/library/functions.html#str) теперь является типом, и [`str()`](https://python-all.ru/3.2/library/functions.html#str) вызывает конструктор этого типа. Этот конструктор вызывает [`PyObject_Str()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Str) для выполнения фактической работы, а [`PyObject_Str()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Str) вызовет этот обработчик.)244245Сигнатура такая же, как у [`PyObject_Str()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Str); она должна возвращать строку или объект Unicode. Эта функция должна возвращать «дружественное» строковое представление объекта, так как это представление будет использоваться, в частности, функцией [`print()`](https://python-all.ru/3.2/library/functions.html#print).246247Если это поле не установлено, вызывается [`PyObject_Repr()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Repr) для возврата строкового представления.248249Это поле наследуется подтипами.250251**getattrofunc `PyTypeObject.tp_getattro`**252253Необязательный указатель на функцию получения атрибута.254255Сигнатура такая же, как у [`PyObject_GetAttr()`](https://python-all.ru/3.2/c-api/object.html#PyObject_GetAttr). Обычно удобно устанавливать это поле в [`PyObject_GenericGetAttr()`](https://python-all.ru/3.2/c-api/object.html#PyObject_GenericGetAttr), который реализует обычный способ поиска атрибутов объекта.256257Это поле наследуется подтипами вместе с `tp_getattr`: подтип наследует как `tp_getattr`, так и `tp_getattro` от своего базового типа, если оба поля `tp_getattr` и `tp_getattro` подтипа равны *NULL*.258259**setattrofunc `PyTypeObject.tp_setattro`**260261Необязательный указатель на функцию установки атрибута.262263Сигнатура такая же, как у [`PyObject_SetAttr()`](https://python-all.ru/3.2/c-api/object.html#PyObject_SetAttr). Обычно удобно устанавливать это поле в [`PyObject_GenericSetAttr()`](https://python-all.ru/3.2/c-api/object.html#PyObject_GenericSetAttr), которая реализует обычный способ установки атрибутов объекта.264265Это поле наследуется подтипами вместе с `tp_setattr`: подтип наследует как `tp_setattr`, так и `tp_setattro` от своего базового типа, если оба поля `tp_setattr` и `tp_setattro` подтипа равны *NULL*.266267**[PyBufferProcs](https://python-all.ru/3.2/c-api/typeobj.html#PyBufferProcs)\* `PyTypeObject.tp_as_buffer`**268269Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих буферный интерфейс. Эти поля описаны в [*Buffer Object Structures*](https://python-all.ru/3.2/c-api/typeobj.html#buffer-structs).270271Поле `tp_as_buffer` не наследуется, но содержащиеся в нём поля наследуются по отдельности.272273**long `PyTypeObject.tp_flags`**274275Это поле представляет собой битовую маску различных флагов. Некоторые флаги указывают на изменённую семантику в определённых ситуациях; другие используются для указания того, что некоторые поля в объекте типа (или в структурах расширения, на которые ссылаются через `tp_as_number`, `tp_as_sequence`, `tp_as_mapping` и `tp_as_buffer`), которые исторически не всегда присутствовали, допустимы; если такой бит флага сброшен, поля типа, которые он защищает, не должны быть доступны и должны считаться имеющими нулевое значение или *NULL*.276277Наследование этого поля сложно. Большинство битов флагов наследуются по отдельности, то есть если у базового типа установлен бит флага, подтип наследует этот бит. Биты флагов, относящиеся к структурам расширения, строго наследуются, если структура расширения наследуется, то есть значение бита флага базового типа копируется в подтип вместе с указателем на структуру расширения. Бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) наследуется вместе с полями `tp_traverse` и `tp_clear`, то есть если бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) сброшен в подтипе, а поля `tp_traverse` и `tp_clear` в подтипе существуют и имеют значения *NULL*.278279В настоящее время определены следующие битовые маски; их можно объединять с помощью оператора `|` для формирования значения поля `tp_flags`. Макрос [`PyType_HasFeature()`](https://python-all.ru/3.2/c-api/type.html#PyType_HasFeature) принимает тип и значение флагов, *tp* и *f*, и проверяет, является ли `tp->tp_flags & f` ненулевым.280281#### `Py_TPFLAGS_HEAPTYPE`282283Этот бит устанавливается, когда сам объект типа выделяется в куче. В этом случае поле `ob_type` его экземпляров считается ссылкой на тип, и объект типа инкрементируется (INCREF), когда создаётся новый экземпляр, и декрементируется (DECREF), когда экземпляр уничтожается (это не относится к экземплярам подтипов; только тип, на который ссылается ob\_type экземпляра, инкрементируется или декрементируется).284285#### `Py_TPFLAGS_BASETYPE`286287Этот бит устанавливается, когда тип может использоваться как базовый тип другого типа. Если этот бит сброшен, тип не может быть унаследован (аналогично «финальному» классу в Java).288289#### `Py_TPFLAGS_READY`290291Этот бит устанавливается, когда объект типа был полностью инициализирован с помощью [`PyType_Ready()`](https://python-all.ru/3.2/c-api/type.html#PyType_Ready).292293#### `Py_TPFLAGS_READYING`294295Этот бит устанавливается, пока [`PyType_Ready()`](https://python-all.ru/3.2/c-api/type.html#PyType_Ready) находится в процессе инициализации объекта типа.296297#### `Py_TPFLAGS_HAVE_GC`298299Этот бит устанавливается, когда объект поддерживает сборку мусора. Если этот бит установлен, экземпляры должны создаваться с помощью [`PyObject_GC_New()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_New) и уничтожаться с помощью [`PyObject_GC_Del()`](https://python-all.ru/3.2/c-api/gcsupport.html#PyObject_GC_Del). Дополнительная информация приведена в разделе [*Поддержка циклической сборки мусора*](https://python-all.ru/3.2/c-api/gcsupport.html#supporting-cycle-detection). Этот бит также означает, что в объекте типа присутствуют поля, связанные с GC: `tp_traverse` и `tp_clear`.300301#### `Py_TPFLAGS_DEFAULT`302303Это битовая маска всех битов, относящихся к существованию определённых полей в объекте типа и его структурах расширения. В настоящее время она включает следующие биты: `Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`, `Py_TPFLAGS_HAVE_VERSION_TAG`.304305**char\* `PyTypeObject.tp_doc`**306307Необязательный указатель на C-строку, завершающуюся NUL, содержащую строку документации для этого объекта типа. Он доступен как атрибут `__doc__` у типа и его экземпляров.308309Это поле *не* наследуется подтипами.310311**[traverseproc](https://python-all.ru/3.2/c-api/gcsupport.html#traverseproc) `PyTypeObject.tp_traverse`**312313Необязательный указатель на функцию обхода для сборщика мусора. Используется только если установлен бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Дополнительную информацию о схеме сборки мусора в Python можно найти в разделе [*Supporting Cyclic Garbage Collection*](https://python-all.ru/3.2/c-api/gcsupport.html#supporting-cycle-detection).314315Указатель `tp_traverse` используется сборщиком мусора для обнаружения циклических ссылок. Типичная реализация функции `tp_traverse` просто вызывает [`Py_VISIT()`](https://python-all.ru/3.2/c-api/gcsupport.html#Py_VISIT) для каждого члена экземпляра, который является объектом Python. Например, это функция `local_traverse()` из модуля расширения [`_thread`](https://python-all.ru/3.2/library/_thread.html#module-_thread):316317```c318static int319local_traverse(localobject *self, visitproc visit, void *arg)320{321    Py_VISIT(self->args);322    Py_VISIT(self->kw);323    Py_VISIT(self->dict);324    return 0;325}326```327328Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/3.2/c-api/gcsupport.html#Py_VISIT) вызывается только для тех членов, которые могут участвовать в циклических ссылках. Хотя есть также член `self->key`, он может быть только *NULL* или строкой Python и поэтому не может быть частью циклической ссылки.329330С другой стороны, даже если известно, что член никогда не может быть частью цикла, в качестве средства отладки может потребоваться посетить его всё равно, чтобы функция `get_referents()` модуля [`gc`](https://python-all.ru/3.2/library/gc.html#module-gc) включала его.331332Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/3.2/c-api/gcsupport.html#Py_VISIT) требует, чтобы параметры *visit* и *arg* функции `local_traverse()` имели именно такие имена; не называйте их как угодно.333334Это поле наследуется подтипами вместе с `tp_clear` и битом флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): бит флага, `tp_traverse` и `tp_clear` наследуются от базового типа, если в подтипе они все равны нулю.335336**[inquiry](https://python-all.ru/3.2/c-api/gcsupport.html#inquiry) `PyTypeObject.tp_clear`**337338Необязательный указатель на функцию очистки для сборщика мусора. Используется только если установлен бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).339340Функция-член `tp_clear` используется для разрыва циклических ссылок в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности все функции `tp_clear` в системе должны объединяться, чтобы разорвать все циклические ссылки. Это тонкий момент, и если есть сомнения, предоставьте функцию `tp_clear`. Например, тип кортежа не реализует функцию `tp_clear`, потому что можно доказать, что ни одна циклическая ссылка не может состоять исключительно из кортежей. Следовательно, функции `tp_clear` других типов должны быть достаточны для разрыва любой циклической ссылки, содержащей кортеж. Это не сразу очевидно, и редко есть веская причина избегать реализации `tp_clear`.341342Реализации `tp_clear` должны удалять ссылки экземпляра на те его члены, которые могут быть объектами Python, и устанавливать указатели на эти члены в *NULL*, как в следующем примере:343344```c345static int346local_clear(localobject *self)347{348    Py_CLEAR(self->key);349    Py_CLEAR(self->args);350    Py_CLEAR(self->kw);351    Py_CLEAR(self->dict);352    return 0;353}354```355356Следует использовать макрос [`Py_CLEAR()`](https://python-all.ru/3.2/c-api/refcounting.html#Py_CLEAR), поскольку очистка ссылок – деликатная операция: ссылка на содержащийся объект не должна уменьшаться до тех пор, пока указатель на содержащийся объект не будет установлен в *NULL*. Это связано с тем, что уменьшение счётчика ссылок может привести к тому, что содержащийся объект станет мусором, что вызовет цепочку действий по его освобождению, которая может включать вызов произвольного кода Python (из-за финализаторов или колбэков слабых ссылок, связанных с содержащимся объектом). Если такой код может снова обратиться к *self*, важно, чтобы указатель на содержащийся объект в этот момент был *NULL*, чтобы *self* знал, что содержащийся объект больше не может использоваться. Макрос [`Py_CLEAR()`](https://python-all.ru/3.2/c-api/refcounting.html#Py_CLEAR) выполняет операции в безопасном порядке.357358Поскольку цель функций `tp_clear` – разрывать циклические ссылки, нет необходимости очищать содержащиеся объекты, такие как строки Python или целые числа Python, которые не могут участвовать в циклических ссылках. С другой стороны, может быть удобно очистить все содержащиеся объекты Python и написать функцию `tp_dealloc` типа так, чтобы она вызывала `tp_clear`.359360Дополнительную информацию о схеме сборки мусора Python можно найти в разделе [*Поддержка циклической сборки мусора*](https://python-all.ru/3.2/c-api/gcsupport.html#supporting-cycle-detection).361362Это поле наследуется подтипами вместе с `tp_traverse` и битом флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): бит флага, `tp_traverse` и `tp_clear` наследуются от базового типа, если в подтипе они все равны нулю.363364**richcmpfunc `PyTypeObject.tp_richcompare`**365366Необязательный указатель на функцию сравнения с сигнатурой: `PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)`.367368Функция должна возвращать результат сравнения (обычно `Py_True` или `Py_False`). Если сравнение не определено, она должна вернуть `Py_NotImplemented`; если произошла другая ошибка – вернуть `NULL` и установить условие исключения.369370> **Примечание**371>372> Если требуется реализовать тип, для которого имеет смысл только ограниченный набор сравнений (например, `==` и `!=`, но не `<` и подобные), следует напрямую возбуждать [`TypeError`](https://python-all.ru/3.2/library/exceptions.html#TypeError) в функции расширенного сравнения.373374Это поле наследуется подтипами вместе с `tp_hash`: подтип наследует `tp_richcompare` и `tp_hash`, когда его собственные `tp_richcompare` и `tp_hash` оба равны *NULL*.375376Следующие константы определены для использования в качестве третьего аргумента для `tp_richcompare` и для [`PyObject_RichCompare()`](https://python-all.ru/3.2/c-api/object.html#PyObject_RichCompare):377378| Константа | Сравнение |379| --- | --- |380| `Py_LT` | `<` |381| `Py_LE` | `<=` |382| `Py_EQ` | `==` |383| `Py_NE` | `!=` |384| `Py_GT` | `>` |385| `Py_GE` | `>=` |386387**long `PyTypeObject.tp_weaklistoffset`**388389Если экземпляры этого типа поддерживают слабые ссылки, это поле больше нуля и содержит смещение в структуре экземпляра до головы списка слабых ссылок (игнорируя заголовок GC, если он присутствует); это смещение используется функциями `PyObject_ClearWeakRefs()` и `PyWeakref_*()`. Структура экземпляра должна содержать поле типа [`PyObject*`](https://python-all.ru/3.2/c-api/structures.html#PyObject), которое инициализируется значением *NULL*.390391Не путайте это поле с `tp_weaklist`; это заголовок списка для слабых ссылок на сам объект типа.392393Это поле наследуется подтипами, но см. правила, перечисленные ниже. Подтип может переопределять это смещение; это означает, что подтип использует другой заголовок списка слабых ссылок, чем базовый тип. Поскольку заголовок списка всегда находится через `tp_weaklistoffset`, это не должно быть проблемой.394395Когда тип, определенный с помощью оператора class, не имеет объявления `__slots__` и ни один из его базовых типов не поддерживает слабые ссылки, тип делается поддерживающим слабые ссылки путем добавления слота заголовка списка слабых ссылок в структуру экземпляра и установки `tp_weaklistoffset` на смещение этого слота.396397Когда объявление `__slots__` типа содержит слот с именем `__weakref__`, этот слот становится заголовком списка слабых ссылок для экземпляров типа, и смещение слота сохраняется в `tp_weaklistoffset` типа.398399Когда объявление `__slots__` типа не содержит слот с именем `__weakref__`, тип наследует своё `tp_weaklistoffset` от своего базового типа.400401**getiterfunc `PyTypeObject.tp_iter`**402403Необязательный указатель на функцию, возвращающую итератор для объекта. Его наличие обычно указывает на то, что экземпляры этого типа являются итерируемыми (хотя последовательности могут быть итерируемыми и без этой функции).404405Эта функция имеет ту же сигнатуру, что и [`PyObject_GetIter()`](https://python-all.ru/3.2/c-api/object.html#PyObject_GetIter).406407Это поле наследуется подтипами.408409**iternextfunc `PyTypeObject.tp_iternext`**410411Необязательный указатель на функцию, возвращающую следующий элемент итератора. Когда итератор исчерпан, она должна вернуть *NULL*; исключение [`StopIteration`](https://python-all.ru/3.2/library/exceptions.html#StopIteration) может быть установлено, а может и нет. При возникновении другой ошибки она также должна вернуть *NULL*. Наличие этой функции указывает, что экземпляры данного типа являются итераторами.412413Типы-итераторы также должны определять функцию `tp_iter`, и эта функция должна возвращать сам экземпляр итератора (а не новый экземпляр итератора).414415Эта функция имеет ту же сигнатуру, что и [`PyIter_Next()`](https://python-all.ru/3.2/c-api/iter.html#PyIter_Next).416417Это поле наследуется подтипами.418419**struct [PyMethodDef](https://python-all.ru/3.2/c-api/structures.html#PyMethodDef)\* `PyTypeObject.tp_methods`**420421Необязательный указатель на статический массив структур [`PyMethodDef`](https://python-all.ru/3.2/c-api/structures.html#PyMethodDef), завершающийся *NULL*, объявляющий обычные методы этого типа.422423Для каждой записи в массиве в словарь типа добавляется запись (см. `tp_dict` ниже), содержащая дескриптор метода.424425Это поле не наследуется подтипами (методы наследуются через другой механизм).426427**struct [PyMemberDef](https://python-all.ru/3.2/c-api/structures.html#PyMemberDef)\* `PyTypeObject.tp_members`**428429Необязательный указатель на статический массив структур [`PyMemberDef`](https://python-all.ru/3.2/c-api/structures.html#PyMemberDef), завершающийся *NULL*, объявляющий обычные элементы данных (поля или слоты) экземпляров этого типа.430431Для каждой записи в массиве в словарь типа добавляется запись (см. `tp_dict` ниже), содержащая дескриптор члена.432433Это поле не наследуется подтипами (члены наследуются через другой механизм).434435**struct PyGetSetDef\* `PyTypeObject.tp_getset`**436437Необязательный указатель на статический массив структур `PyGetSetDef`, завершающийся *NULL*, объявляющий вычисляемые атрибуты экземпляров этого типа.438439Для каждой записи в массиве в словарь типа добавляется запись (см. `tp_dict` ниже), содержащая дескриптор getset.440441Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).442443Документация для PyGetSetDef:444445```c446typedef PyObject *(*getter)(PyObject *, void *);447typedef int (*setter)(PyObject *, PyObject *, void *);448449typedef struct PyGetSetDef {450    char *name;    /* имя атрибута */451    getter get;    /* C-функция для получения атрибута */452    setter set;    /* C-функция для установки атрибута */453    char *doc;     /* необязательная строка документации */454    void *closure; /* необязательные дополнительные данные для геттера и сеттера */455} PyGetSetDef;456```457458**[PyTypeObject](https://python-all.ru/3.2/c-api/type.html#PyTypeObject)\* `PyTypeObject.tp_base`**459460Необязательный указатель на базовый тип, от которого наследуются свойства типа. На этом уровне поддерживается только одиночное наследование; множественное наследование требует динамического создания объекта типа вызовом метатипа.461462Это поле не наследуется подтипами (очевидно), но по умолчанию оно равно `&PyBaseObject_Type` (которое программистам Python известно как тип [`object`](https://python-all.ru/3.2/library/functions.html#object)).463464**[PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject)\* `PyTypeObject.tp_dict`**465466Словарь типа сохраняется здесь функцией [`PyType_Ready()`](https://python-all.ru/3.2/c-api/type.html#PyType_Ready).467468Обычно это поле должно быть инициализировано значением *NULL* перед вызовом PyType\_Ready; его также можно инициализировать словарём, содержащим начальные атрибуты типа. После того как [`PyType_Ready()`](https://python-all.ru/3.2/c-api/type.html#PyType_Ready) инициализирует тип, в этот словарь можно добавлять дополнительные атрибуты только если они не соответствуют перегруженным операциям (например, [`__add__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__add__)).469470Это поле не наследуется подтипами (хотя определённые здесь атрибуты наследуются через другой механизм).471472> **Предупреждение**473>474> Небезопасно использовать [`PyDict_SetItem()`](https://python-all.ru/3.2/c-api/dict.html#PyDict_SetItem) для `tp_dict` или иным образом изменять его с помощью C-API словарей.475476**descrgetfunc `PyTypeObject.tp_descr_get`**477478Необязательный указатель на функцию «descriptor get».479480Сигнатура функции:481482```c483PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);484```485486Это поле наследуется подтипами.487488**descrsetfunc `PyTypeObject.tp_descr_set`**489490Необязательный указатель на функцию «установки дескриптора».491492Сигнатура функции:493494```c495int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);496```497498Это поле наследуется подтипами.499500**long `PyTypeObject.tp_dictoffset`**501502Если экземпляры этого типа имеют словарь, содержащий переменные экземпляра, это поле не равно нулю и содержит смещение словаря переменных экземпляра в структуре экземпляров типа; это смещение используется функцией [`PyObject_GenericGetAttr()`](https://python-all.ru/3.2/c-api/object.html#PyObject_GenericGetAttr).503504Не путайте это поле с `tp_dict`; это словарь для атрибутов самого объекта типа.505506Если значение этого поля больше нуля, оно задает смещение от начала структуры экземпляра. Если значение меньше нуля, оно задает смещение от *конца* структуры экземпляра. Отрицательное смещение использовать дороже, и его следует применять только когда структура экземпляра содержит часть переменной длины. Это используется, например, для добавления словаря переменных экземпляра в подтипы [`str`](https://python-all.ru/3.2/library/functions.html#str) или [`tuple`](https://python-all.ru/3.2/library/functions.html#tuple). Обратите внимание, что поле `tp_basicsize` должно учитывать словарь, добавленный в конец в этом случае, даже если словарь не включен в базовую компоновку объекта. В системе с размером указателя 4 байта поле `tp_dictoffset` должно быть установлено в `-4`, чтобы указать, что словарь находится в самом конце структуры.507508Реальное смещение словаря в экземпляре можно вычислить из отрицательного `tp_dictoffset` следующим образом:509510```c511dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset512if dictoffset is not aligned on sizeof(void*):513    round up to sizeof(void*)514```515516где `tp_basicsize`, `tp_itemsize` и `tp_dictoffset` берутся из объекта типа, а `ob_size` – из экземпляра. Используется абсолютное значение, потому что целые числа используют знак `ob_size` для хранения знака числа. (Никогда не требуется выполнять этот расчет самостоятельно; он выполняется за вас функцией `_PyObject_GetDictPtr()`.)517518Это поле наследуется подтипами, но см. правила, перечисленные ниже. Подтип может переопределить это смещение; это означает, что экземпляры подтипа хранят словарь по другому смещению, чем базовый тип. Поскольку словарь всегда находится через `tp_dictoffset`, это не должно быть проблемой.519520Когда тип, определенный с помощью оператора class, не имеет объявления `__slots__`, и ни один из его базовых типов не имеет словаря переменных экземпляра, в компоновку экземпляра добавляется слот словаря, и `tp_dictoffset` устанавливается в смещение этого слота.521522Когда тип, определенный с помощью оператора class, имеет объявление `__slots__`, тип наследует свое `tp_dictoffset` от своего базового типа.523524(Добавление слота с именем `__dict__` в объявление `__slots__` не дает ожидаемого эффекта, это только вызывает путаницу. Однако, возможно, эту возможность стоит добавить по аналогии с `__weakref__`.)525526**initproc `PyTypeObject.tp_init`**527528Необязательный указатель на функцию инициализации экземпляра.529530Эта функция соответствует методу классов [`__init__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__init__). Как и для [`__init__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__init__), можно создать экземпляр, не вызывая [`__init__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__init__), а также можно переинициализировать экземпляр, повторно вызвав его метод [`__init__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__init__).531532Сигнатура функции:533534```c535int tp_init(PyObject *self, PyObject *args, PyObject *kwds)536```537538Аргумент self – это инициализируемый экземпляр; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова [`__init__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__init__).539540Функция `tp_init`, если она не равна *NULL*, вызывается при обычном создании экземпляра путем вызова его типа, после того как функция `tp_new` типа вернула экземпляр этого типа. Если функция `tp_new` возвращает экземпляр другого типа, который не является подтипом исходного типа, функция `tp_init` не вызывается; если `tp_new` возвращает экземпляр подтипа исходного типа, вызывается `tp_init` подтипа.541542Это поле наследуется подтипами.543544**allocfunc `PyTypeObject.tp_alloc`**545546Необязательный указатель на функцию выделения экземпляра.547548Сигнатура функции:549550```c551PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)552```553554Назначение этой функции – разделить выделение памяти и ее инициализацию. Она должна возвращать указатель на блок памяти достаточной длины для экземпляра, с подходящим выравниванием, инициализированный нулями, но с `ob_refcnt`, установленным в `1`, и `ob_type`, установленным в аргумент type. Если `tp_itemsize` типа не равен нулю, поле `ob_size` объекта должно быть инициализировано значением *nitems*, а длина выделенного блока памяти должна быть `tp_basicsize + nitems*tp_itemsize`, округленная до кратного `sizeof(void*)`; в противном случае *nitems* не используется, и длина блока должна быть `tp_basicsize`.555556Не используйте эту функцию для любой другой инициализации экземпляра, даже для выделения дополнительной памяти; это должно делаться через `tp_new`.557558Это поле наследуется статическими подтипами, но не динамическими (подтипами, созданными с помощью оператора class); у последних это поле всегда устанавливается в [`PyType_GenericAlloc()`](https://python-all.ru/3.2/c-api/type.html#PyType_GenericAlloc), чтобы принудительно применить стандартную стратегию выделения памяти в куче. Это же значение рекомендуется и для статически определённых типов.559560**newfunc `PyTypeObject.tp_new`**561562Необязательный указатель на функцию создания экземпляра.563564Если для данного типа эта функция равна *NULL*, то этот тип нельзя вызвать для создания новых экземпляров; предполагается, что существует другой способ создания экземпляров, например, фабричная функция.565566Сигнатура функции:567568```c569PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)570```571572Аргумент subtype – это тип создаваемого объекта; аргументы *args* и *kwds* представляют позиционные и ключевые аргументы вызова типа. Обратите внимание, что subtype не обязательно должен совпадать с типом, чья функция `tp_new` вызывается; это может быть подтип этого типа (но не несвязанный тип).573574Функция `tp_new` должна вызывать `subtype->tp_alloc(subtype, nitems)` для выделения пространства под объект, а затем выполнять только минимально необходимую дальнейшую инициализацию. Инициализацию, которую можно безопасно игнорировать или повторять, следует помещать в обработчик `tp_init`. Хорошее практическое правило: для неизменяемых типов вся инициализация должна происходить в `tp_new`, тогда как для изменяемых типов большую часть инициализации следует отложить до `tp_init`.575576Это поле наследуется подтипами, за исключением статических типов, у которых `tp_base` равен *NULL* или `&PyBaseObject_Type`.577578**destructor `PyTypeObject.tp_free`**579580Необязательный указатель на функцию освобождения экземпляра. Её сигнатура – `freefunc`:581582```c583void tp_free(void *)584```585586Инициализатор, совместимый с этой сигнатурой – `PyObject_Free()`.587588Это поле наследуется статическими подтипами, но не динамическими (подтипами, созданными с помощью оператора class); у последних это поле устанавливается в деаллокатор, подходящий для [`PyType_GenericAlloc()`](https://python-all.ru/3.2/c-api/type.html#PyType_GenericAlloc) и значения флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).589590**[inquiry](https://python-all.ru/3.2/c-api/gcsupport.html#inquiry) `PyTypeObject.tp_is_gc`**591592Необязательный указатель на функцию, вызываемую сборщиком мусора.593594Сборщику мусора нужно знать, является ли конкретный объект собираемым или нет. Обычно достаточно посмотреть на поле `tp_flags` типа объекта и проверить бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.2/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Но некоторые типы имеют смесь статически и динамически выделенных экземпляров, причём статически выделенные экземпляры не собираются. Такие типы должны определить эту функцию; она должна возвращать `1` для собираемого экземпляра и `0` для несобираемого. Сигнатура:595596```c597int tp_is_gc(PyObject *self)598```599600(Единственный пример этого – сами типы. Метатип [`PyType_Type`](https://python-all.ru/3.2/c-api/type.html#PyType_Type) определяет эту функцию, чтобы различать статически и динамически выделенные типы.)601602Это поле наследуется подтипами.603604**[PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject)\* `PyTypeObject.tp_bases`**605606Кортеж базовых типов.607608Это устанавливается для типов, созданных с помощью оператора class. Для статически определённых типов оно должно быть равно *NULL*.609610Это поле не наследуется.611612**[PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject)\* `PyTypeObject.tp_mro`**613614Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая [`object`](https://python-all.ru/3.2/library/functions.html#object), в порядке разрешения методов (MRO).615616Это поле не наследуется; оно вычисляется заново функцией [`PyType_Ready()`](https://python-all.ru/3.2/c-api/type.html#PyType_Ready).617618**[PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject)\* `PyTypeObject.tp_cache`**619620Не используется. Не наследуется. Только для внутреннего использования.621622**[PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject)\* `PyTypeObject.tp_subclasses`**623624Список слабых ссылок на подклассы. Не наследуется. Только для внутреннего использования.625626**[PyObject](https://python-all.ru/3.2/c-api/structures.html#PyObject)\* `PyTypeObject.tp_weaklist`**627628Голова списка слабых ссылок для слабых ссылок на этот объект типа. Не наследуется. Только для внутреннего использования.629630Оставшиеся поля определяются только если определён макрос тестирования функциональности `COUNT_ALLOCS`, и предназначены только для внутреннего использования. Они dокументированы здесь для полноты. Ни одно из этих полей не наследуется подтипами.631632**Py\_ssize\_t `PyTypeObject.tp_allocs`**633634Количество выделений памяти.635636**Py\_ssize\_t `PyTypeObject.tp_frees`**637638Количество освобождений.639640**Py\_ssize\_t `PyTypeObject.tp_maxalloc`**641642Максимальное количество одновременно выделенных объектов.643644**[PyTypeObject](https://python-all.ru/3.2/c-api/type.html#PyTypeObject)\* `PyTypeObject.tp_next`**645646Указатель на следующий объект типа с ненулевым полем `tp_allocs`.647648Также следует отметить, что в Python со сборкой мусора tp\_dealloc может вызываться из любого потока Python, а не только из того, который создал объект (если объект становится частью цикла подсчёта ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Это не проблема для вызовов Python API, поскольку поток, в котором вызывается tp\_dealloc, будет владеть глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект, в свою очередь, уничтожает объекты из какой-либо другой библиотеки C или C++, следует соблюдать осторожность, чтобы убедиться, что уничтожение этих объектов в потоке, вызвавшем tp\_dealloc, не нарушит никаких предположений библиотеки.649650# Структуры числовых объектов651652**`PyNumberMethods`**653654Эта структура содержит указатели на функции, которые объект использует для реализации числового протокола. Каждая функция используется одноимённой функцией, описанной в разделе [*Числовой протокол*](https://python-all.ru/3.2/c-api/number.html#number).655656Вот определение структуры:657658```c659typedef struct {660     binaryfunc nb_add;661     binaryfunc nb_subtract;662     binaryfunc nb_multiply;663     binaryfunc nb_remainder;664     binaryfunc nb_divmod;665     ternaryfunc nb_power;666     unaryfunc nb_negative;667     unaryfunc nb_positive;668     unaryfunc nb_absolute;669     inquiry nb_bool;670     unaryfunc nb_invert;671     binaryfunc nb_lshift;672     binaryfunc nb_rshift;673     binaryfunc nb_and;674     binaryfunc nb_xor;675     binaryfunc nb_or;676     unaryfunc nb_int;677     void *nb_reserved;678     unaryfunc nb_float;679680     binaryfunc nb_inplace_add;681     binaryfunc nb_inplace_subtract;682     binaryfunc nb_inplace_multiply;683     binaryfunc nb_inplace_remainder;684     ternaryfunc nb_inplace_power;685     binaryfunc nb_inplace_lshift;686     binaryfunc nb_inplace_rshift;687     binaryfunc nb_inplace_and;688     binaryfunc nb_inplace_xor;689     binaryfunc nb_inplace_or;690691     binaryfunc nb_floor_divide;692     binaryfunc nb_true_divide;693     binaryfunc nb_inplace_floor_divide;694     binaryfunc nb_inplace_true_divide;695696     unaryfunc nb_index;697} PyNumberMethods;698```699700> **Примечание**701>702> Бинарные и тернарные функции должны проверять тип всех своих операндов и выполнять необходимые преобразования (хотя бы один из операндов является экземпляром определённого типа). Если операция не определена для данных операндов, бинарные и тернарные функции должны вернуть `Py_NotImplemented`; если произошла другая ошибка, они должны вернуть `NULL` и установить исключение.703704> **Примечание**705>706> Поле `nb_reserved` всегда должно быть `NULL`. Ранее оно называлось `nb_long` и было переименовано в Python 3.0.1.707708# Структуры объектов отображения709710**`PyMappingMethods`**711712Эта структура хранит указатели на функции, которые объект использует для реализации протокола отображения. Она содержит три члена:713714**lenfunc `PyMappingMethods.mp_length`**715716Эта функция используется функциями [`PyMapping_Length()`](https://python-all.ru/3.2/c-api/mapping.html#PyMapping_Length) и [`PyObject_Size()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Size) и имеет ту же сигнатуру. Этот слот может быть установлен в *NULL*, если у объекта нет определённой длины.717718**binaryfunc `PyMappingMethods.mp_subscript`**719720Эта функция используется функцией [`PyObject_GetItem()`](https://python-all.ru/3.2/c-api/object.html#PyObject_GetItem) и имеет ту же сигнатуру. Этот слот должен быть заполнен, чтобы функция [`PyMapping_Check()`](https://python-all.ru/3.2/c-api/mapping.html#PyMapping_Check) возвращала `1`; в противном случае он может быть *NULL*.721722**objobjargproc `PyMappingMethods.mp_ass_subscript`**723724Эта функция используется функцией [`PyObject_SetItem()`](https://python-all.ru/3.2/c-api/object.html#PyObject_SetItem) и имеет ту же сигнатуру. Если этот слот равен *NULL*, объект не поддерживает присваивание по индексу.725726# Структуры объектов последовательностей727728**`PySequenceMethods`**729730Эта структура содержит указатели на функции, которые объект использует для реализации протокола последовательности.731732**lenfunc `PySequenceMethods.sq_length`**733734Эта функция используется функциями [`PySequence_Size()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_Size) и [`PyObject_Size()`](https://python-all.ru/3.2/c-api/object.html#PyObject_Size), и имеет ту же сигнатуру.735736**binaryfunc `PySequenceMethods.sq_concat`**737738Эта функция используется [`PySequence_Concat()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_Concat) и имеет ту же сигнатуру. Она также используется оператором `+` после попытки числового сложения через слот `tp_as_number.nb_add`.739740**ssizeargfunc `PySequenceMethods.sq_repeat`**741742Эта функция используется [`PySequence_Repeat()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_Repeat) и имеет ту же сигнатуру. Она также используется оператором `*` после попытки числового умножения через слот `tp_as_number.nb_mul`.743744**ssizeargfunc `PySequenceMethods.sq_item`**745746Эта функция используется функцией [`PySequence_GetItem()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_GetItem) и имеет ту же сигнатуру. Этот слот должен быть заполнен, чтобы функция [`PySequence_Check()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_Check) возвращала `1`; в противном случае он может быть *NULL*.747748Отрицательные индексы обрабатываются следующим образом: если слот `sq_length` заполнен, он вызывается и длина последовательности используется для вычисления положительного индекса, который передаётся в `sq_item`. Если `sq_length` равен *NULL*, индекс передаётся в функцию как есть.749750**ssizeobjargproc `PySequenceMethods.sq_ass_item`**751752Эта функция используется функцией [`PySequence_SetItem()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_SetItem) и имеет ту же сигнатуру. Этот слот может быть оставлен равным *NULL*, если объект не поддерживает присваивание по индексу.753754**objobjproc `PySequenceMethods.sq_contains`**755756Эта функция может использоваться [`PySequence_Contains()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_Contains) и имеет ту же\\nсигнатуру. Этот слот можно оставить равным *NULL*; в этом случае\\n[`PySequence_Contains()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_Contains) просто обходит последовательность, пока не найдёт\\nсовпадение.757758**binaryfunc `PySequenceMethods.sq_inplace_concat`**759760Эта функция используется [`PySequence_InPlaceConcat()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_InPlaceConcat) и имеет ту же\\nсигнатуру. Она должна изменить свой первый операнд и вернуть его.761762**ssizeargfunc `PySequenceMethods.sq_inplace_repeat`**763764Эта функция используется [`PySequence_InPlaceRepeat()`](https://python-all.ru/3.2/c-api/sequence.html#PySequence_InPlaceRepeat) и имеет ту же\\nсигнатуру. Она должна изменить свой первый операнд и вернуть его.765766# Структуры объектов буфера767768[*Интерфейс буфера*](https://python-all.ru/3.2/c-api/buffer.html#bufferobjects) предоставляет модель, в которой объект может раскрывать свои внутренние данные.769770Если объект не предоставляет интерфейс буфера, то его член `tp_as_buffer` в структуре [`PyTypeObject`](https://python-all.ru/3.2/c-api/type.html#PyTypeObject) должен быть *NULL*. В противном случае `tp_as_buffer` будет указывать на структуру [`PyBufferProcs`](https://python-all.ru/3.2/c-api/typeobj.html#PyBufferProcs).771772**`PyBufferProcs`**773774Структура, используемая для хранения указателей на функции, определяющие реализацию протокола буфера.775776**getbufferproc `bf_getbuffer`**777778Это должно заполнить [`Py_buffer`](https://python-all.ru/3.2/c-api/buffer.html#Py_buffer) необходимыми данными для экспорта типа. Сигнатура `getbufferproc`: `int (PyObject *obj, Py_buffer *view, int flags)`. *obj* – экспортируемый объект, *view* – структура [`Py_buffer`](https://python-all.ru/3.2/c-api/buffer.html#Py_buffer), которую нужно заполнить, а *flags* задаёт условия доступа к памяти, требуемые вызывающей стороной. (См. [`PyObject_GetBuffer()`](https://python-all.ru/3.2/c-api/buffer.html#PyObject_GetBuffer) для полного списка флагов.) `bf_getbuffer` отвечает за заполнение *view* соответствующими данными. (В простых случаях можно использовать `PyBuffer_FillView()`.) См. [`Py_buffer`](https://python-all.ru/3.2/c-api/buffer.html#Py_buffer) документации, чтобы узнать, что нужно заполнить.779780**releasebufferproc `bf_releasebuffer`**781782Это должно освобождать ресурсы буфера. Сигнатура `releasebufferproc`: `void (PyObject *obj, Py_buffer *view)`. Если функция `bf_releasebuffer` не предоставлена (т.е. равна *NULL*), то её никогда не нужно вызывать.783784Экспортёр буферного интерфейса должен гарантировать, что любая память, на которую указывает структура [`Py_buffer`](https://python-all.ru/3.2/c-api/buffer.html#Py_buffer), остаётся действительной до вызова releasebuffer. Экспортёрам потребуется определить функцию `bf_releasebuffer`, если они могут перераспределять свою память, шаги (strides), форму, подофсеты (suboffsets) или переменные формата, которые могут совместно использоваться через struct bufferinfo.785786См. [`PyBuffer_Release()`](https://python-all.ru/3.2/c-api/buffer.html#PyBuffer_Release).787