typeobj.md
1> **Источник:** https://python-all.ru/2.7/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/2.7/c-api/type.html#c.PyTypeObject). Объекты типа можно обрабатывать с помощью любой из функций `PyObject_*()` или `PyType_*()`, но для большинства приложений Python они не представляют большого интереса. Эти объекты являются основой поведения объектов, поэтому они очень важны как для самого интерпретатора, так и для любых модулей расширения, реализующих новые типы.1011Объекты типа довольно велики по сравнению с большинством стандартных типов. Причина такого размера в том, что каждый объект типа хранит большое количество значений, в основном указателей на функции C, каждый из которых реализует небольшую часть функциональности типа. Поля объекта типа подробно рассматриваются в этом разделе. Поля будут описаны в порядке их появления в структуре.1213Определения типов: unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc, intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, cmpfunc, reprfunc, hashfunc1415Определение структуры для [`PyTypeObject`](https://python-all.ru/2.7/c-api/type.html#c.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 cmpfunc tp_compare;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 /* Назначенное значение в версии 2.0 */55 /* вызов функции для всех доступных объектов */56 traverseproc tp_traverse;5758 /* удаление ссылок на содержащиеся объекты */59 inquiry tp_clear;6061 /* Назначенное значение в версии 2.1 */62 /* расширенные сравнения */63 richcmpfunc tp_richcompare;6465 /* включение слабых ссылок */66 long tp_weaklistoffset;6768 /* Добавлено в версии 2.2 */69 /* Итераторы */70 getiterfunc tp_iter;71 iternextfunc tp_iternext;7273 /* Дескриптор атрибутов и механизмы подклассов */74 struct PyMethodDef *tp_methods;75 struct PyMemberDef *tp_members;76 struct PyGetSetDef *tp_getset;77 struct _typeobject *tp_base;78 PyObject *tp_dict;79 descrgetfunc tp_descr_get;80 descrsetfunc tp_descr_set;81 long tp_dictoffset;82 initproc tp_init;83 allocfunc tp_alloc;84 newfunc tp_new;85 freefunc tp_free; /* Низкоуровневая процедура освобождения памяти */86 inquiry tp_is_gc; /* Для PyObject_IS_GC */87 PyObject *tp_bases;88 PyObject *tp_mro; /* порядок разрешения методов */89 PyObject *tp_cache;90 PyObject *tp_subclasses;91 PyObject *tp_weaklist;9293} PyTypeObject;94```9596Структура объекта-типа расширяет структуру [`PyVarObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyVarObject). Поле `ob_size` используется для динамических типов (создаваемых с помощью `type_new()`, обычно вызываемого из объявления класса). Обратите внимание, что [`PyType_Type`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Type) (метатип) инициализирует [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), что означает, что его экземпляры (т.е. объекты-типы) *должны* иметь поле `ob_size`.9798**[PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject)\* `PyObject._ob_next`**99100**[PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject)\* `PyObject._ob_prev`**101102Эти поля присутствуют только тогда, когда определён макрос `Py_TRACE_REFS`. Их инициализация значением *NULL* выполняется макросом `PyObject_HEAD_INIT`. Для статически выделенных объектов эти поля всегда остаются *NULL*. Для динамически выделенных объектов эти два поля используются для включения объекта в двусвязный список *всех* живых объектов в куче. Это может быть использовано для различных целей отладки; в настоящее время единственное применение – вывод объектов, которые всё ещё живы в конце выполнения, когда установлена переменная окружения [`PYTHONDUMPREFS`](https://python-all.ru/2.7/using/cmdline.html#envvar-PYTHONDUMPREFS).103104Эти поля не наследуются подтипами.105106**Py\_ssize\_t `PyObject.ob_refcnt`**107108Это счётчик ссылок объекта-типа, инициализируемый значением `1` макросом `PyObject_HEAD_INIT`. Обратите внимание: для статически выделенных объектов-типов экземпляры типа (объекты, у которых `ob_type` указывает обратно на тип) *не* считаются ссылками. Но для динамически выделенных объектов-типов экземпляры *считаются* ссылками.109110Это поле не наследуется подтипами.111112Изменено в версии 2.5: Ранее это поле имело тип `int`. Это может потребовать изменений в коде для корректной поддержки 64-битных систем.113114**[PyTypeObject](https://python-all.ru/2.7/c-api/type.html#c.PyTypeObject)\* `PyObject.ob_type`**115116Это тип типа, то есть его метатип. Он инициализируется аргументом макроса `PyObject_HEAD_INIT`, и его значением обычно должно быть `&PyType_Type`. Однако для динамически загружаемых модулей расширения, которые должны работать на Windows (по крайней мере), компилятор сообщает, что это недопустимый инициализатор. Поэтому принято передавать *NULL* макросу `PyObject_HEAD_INIT` и инициализировать это поле явно в начале функции инициализации модуля, до выполнения каких-либо других действий. Обычно это делается так:117118```c119Foo_Type.ob_type = &PyType_Type;120```121122Это должно быть сделано до создания любых экземпляров типа. [`PyType_Ready()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Ready) проверяет, является ли `ob_type` *NULL*, и если да, инициализирует его: в Python 2.2 он устанавливается в `&PyType_Type`; в Python 2.2.1 и позднее он инициализируется полем `ob_type` базового класса. [`PyType_Ready()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Ready) не изменяет это поле, если оно не равно нулю.123124В Python 2.2 это поле не наследуется подтипами. В 2.2.1, а также в 2.3 и более поздних версиях, оно наследуется подтипами.125126**Py\_ssize\_t `PyVarObject.ob_size`**127128Для статически выделенных объектов-типов это поле должно быть инициализировано нулём. Для динамически выделенных объектов-типов это поле имеет особый внутренний смысл.129130Это поле не наследуется подтипами.131132**char\* `PyTypeObject.tp_name`**133134Указатель на строку, завершающуюся NUL, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов это должно быть просто имя типа. Если модуль является подмодулем пакета, полное имя пакета является частью полного имени модуля. Например, тип с именем `T`, определённый в модуле `M` в подпакете `Q` пакета `P`, должен иметь инициализатор [`tp_name`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_name) со значением `"P.Q.M.T"`.135136Для динамически выделенных объектов-типов это должно быть просто имя типа, а имя модуля явно хранится в словаре типа как значение для ключа `'__module__'`.137138Для статически выделенных объектов-типов поле tp\_name должно содержать точку. Всё до последней точки становится доступным как атрибут `__module__`, а всё после последней точки – как атрибут [`__name__`](https://python-all.ru/2.7/library/stdtypes.html#definition.__name__).139140Если точка отсутствует, всё поле [`tp_name`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_name) становится доступным как атрибут [`__name__`](https://python-all.ru/2.7/library/stdtypes.html#definition.__name__), а атрибут `__module__` не определён (если только не задан явно в словаре, как описано выше). Это означает, что ваш тип невозможно будет сериализовать с помощью pickle. Кроме того, он не будет отображаться в документации модуля, создаваемой pydoc.141142Это поле не наследуется подтипами.143144**Py\_ssize\_t `PyTypeObject.tp_basicsize`**145146**Py\_ssize\_t `PyTypeObject.tp_itemsize`**147148Эти поля позволяют вычислить размер экземпляров типа в байтах.149150Существует два вида типов: типы с экземплярами фиксированной длины имеют нулевое [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) поле, типы с экземплярами переменной длины имеют ненулевое [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) поле. Для типа с экземплярами фиксированной длины все экземпляры имеют одинаковый размер, указанный в [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).151152Для типа с экземплярами переменной длины экземпляры должны иметь поле `ob_size`, и размер экземпляра равен [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) плюс N, умноженное на [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), где N – это «длина» объекта. Значение N обычно хранится в поле `ob_size` экземпляра. Есть исключения: например, длинные целые (long ints) используют отрицательное `ob_size` для обозначения отрицательного числа, и N в этом случае равно `abs(ob_size)`. Кроме того, наличие поля `ob_size` в структуре экземпляра не означает, что структура экземпляра имеет переменную длину (например, структура для типа списка имеет экземпляры фиксированной длины, но эти экземпляры содержат значимое поле `ob_size`).153154Базовый размер включает поля экземпляра, объявленные макросом [`PyObject_HEAD`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject_HEAD) или [`PyObject_VAR_HEAD`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject_VAR_HEAD) (в зависимости от того, какой из них используется для объявления структуры экземпляра), и он, в свою очередь, включает поля `_ob_prev` и `_ob_next`, если они присутствуют. Это означает, что единственный правильный способ получить инициализатор для [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) – это использовать оператор `sizeof` для структуры, используемой для объявления макета экземпляра. Базовый размер не включает размер заголовка GC (это нововведение в Python 2.2; в версиях 2.1 и 2.0 размер заголовка GC включался в [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize)).155156Эти поля наследуются подтипами независимо друг от друга. Если базовый тип имеет ненулевое [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), обычно небезопасно устанавливать [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) в другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).157158Замечание о выравнивании: если переменные элементы требуют определённого выравнивания, это должно быть обеспечено значением [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize). Пример: предположим, тип реализует массив `double`. [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) равно `sizeof(double)`. Программист должен гарантировать, что [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) кратно `sizeof(double)` (при условии, что это и есть требование выравнивания для `double`).159160**destructor `PyTypeObject.tp_dealloc`**161162Указатель на функцию деструктора экземпляра. Эта функция должна быть определена, если только тип не гарантирует, что его экземпляры никогда не будут освобождены (как в случае с синглтонами `None` и `Ellipsis`).163164Функция деструктора вызывается макросами [`Py_DECREF()`](https://python-all.ru/2.7/c-api/refcounting.html#c.Py_DECREF) и [`Py_XDECREF()`](https://python-all.ru/2.7/c-api/refcounting.html#c.Py_XDECREF), когда счётчик ссылок становится равным нулю. На этом этапе экземпляр всё ещё существует, но на него нет ссылок. Функция деструктора должна освободить все ссылки, которыми владеет экземпляр, освободить все буферы памяти, принадлежащие экземпляру (используя функцию освобождения, соответствующую функции выделения, которая использовалась для выделения буфера), и, наконец (в качестве последнего действия), вызвать функцию [`tp_free`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_free) типа. Если тип не является подтипируемым (не имеет установленного флага [`Py_TPFLAGS_BASETYPE`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_BASETYPE)), допускается вызывать деаллокатор объекта напрямую, а не через [`tp_free`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_free). Деаллокатором объекта должен быть тот, который использовался для выделения экземпляра; обычно это [`PyObject_Del()`](https://python-all.ru/2.7/c-api/allocation.html#c.PyObject_Del), если экземпляр был выделен с помощью [`PyObject_New()`](https://python-all.ru/2.7/c-api/allocation.html#c.PyObject_New) или `PyObject_VarNew()`, или [`PyObject_GC_Del()`](https://python-all.ru/2.7/c-api/gcsupport.html#c.PyObject_GC_Del), если экземпляр был выделен с помощью [`PyObject_GC_New()`](https://python-all.ru/2.7/c-api/gcsupport.html#c.PyObject_GC_New) или [`PyObject_GC_NewVar()`](https://python-all.ru/2.7/c-api/gcsupport.html#c.PyObject_GC_NewVar).165166Это поле наследуется подтипами.167168**printfunc `PyTypeObject.tp_print`**169170Необязательный указатель на функцию печати экземпляра.171172Функция печати вызывается только тогда, когда экземпляр выводится в *реальный* файл; при выводе в псевдофайл (например, экземпляр [`StringIO`](https://python-all.ru/2.7/library/stringio.html#StringIO.StringIO)) вызывается функция [`tp_repr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_repr) или [`tp_str`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_str) экземпляра для преобразования его в строку. Они также вызываются, когда поле [`tp_print`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_print) типа равно *NULL*. Тип никогда не должен реализовывать [`tp_print`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_print) таким образом, чтобы выдавать вывод, отличный от того, что дали бы [`tp_repr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_repr) или [`tp_str`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_str).173174Функция печати вызывается с той же сигнатурой, что и [`PyObject_Print()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Print): `int tp_print(PyObject *self, FILE *file, int flags)`. Аргумент *self* – это печатаемый экземпляр. Аргумент *file* – это файл stdio, в который он должен быть выведен. Аргумент *flags* состоит из битовых флагов. Единственный определённый в настоящее время бит флага – `Py_PRINT_RAW`. Когда бит флага `Py_PRINT_RAW` установлен, экземпляр должен выводиться так же, как его отформатировал бы [`tp_str`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_str); когда бит флага `Py_PRINT_RAW` сброшен, экземпляр должен выводиться так же, как его отформатировал бы [`tp_repr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_repr). Функция должна возвращать `-1` и устанавливать условие исключения при возникновении ошибки во время сравнения.175176Возможно, поле [`tp_print`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_print) будет объявлено устаревшим. В любом случае рекомендуется не определять [`tp_print`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_print), а вместо этого полагаться на [`tp_repr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_repr) и [`tp_str`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_str) для печати.177178Это поле наследуется подтипами.179180**getattrfunc `PyTypeObject.tp_getattr`**181182Необязательный указатель на функцию получения строки атрибута.183184Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция [`tp_getattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro), но принимает C-строку вместо объекта строки Python для указания имени атрибута. Сигнатура:185186```c187PyObject * tp_getattr(PyObject *o, char *attr_name);188```189190Это поле наследуется подтипами вместе с [`tp_getattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro): подтип наследует как [`tp_getattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr), так и [`tp_getattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr) и [`tp_getattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) подтипа оба равны *NULL*.191192**setattrfunc `PyTypeObject.tp_setattr`**193194Необязательный указатель на функцию для установки и удаления атрибутов.195196Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция [`tp_setattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro), но принимает C-строку вместо объекта строки Python для указания имени атрибута. Сигнатура:197198```c199PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v);200```201202Аргумент *v* устанавливается в *NULL* для удаления атрибута. Это поле наследуется подтипами вместе с [`tp_setattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro): подтип наследует как [`tp_setattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr), так и [`tp_setattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro) от своего базового типа, когда оба поля [`tp_setattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr) и [`tp_setattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro) подтипа равны *NULL*.203204**cmpfunc `PyTypeObject.tp_compare`**205206Необязательный указатель на функцию тройного сравнения.207208Сигнатура такая же, как у [`PyObject_Compare()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Compare). Функция должна возвращать `1`, если *self* больше *other*, `0`, если *self* равно *other*, и `-1`, если *self* меньше *other*. Она должна возвращать `-1` и устанавливать условие исключения при возникновении ошибки во время сравнения.209210Это поле наследуется подтипами вместе с [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_hash): подтип наследует все три: [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare), [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_hash), когда [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare), [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа все равны *NULL*.211212**reprfunc `PyTypeObject.tp_repr`**213214Необязательный указатель на функцию, реализующую встроенную функцию [`repr()`](https://python-all.ru/2.7/library/functions.html#repr).215216Сигнатура такая же, как для [`PyObject_Repr()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Repr); она должна возвращать строку или объект Unicode. В идеале эта функция должна возвращать строку, которая при передаче в [`eval()`](https://python-all.ru/2.7/library/functions.html#eval) в подходящем окружении возвращает объект с тем же значением. Если это невозможно, она должна возвращать строку, начинающуюся с `'<'` и заканчивающуюся `'>'`, из которой можно вывести как тип, так и значение объекта.217218Если это поле не задано, возвращается строка вида `<%s object at %p>`, где `%s` заменяется именем типа, а `%p` – адресом памяти объекта.219220Это поле наследуется подтипами.221222**[PyNumberMethods](https://python-all.ru/2.7/c-api/typeobj.html#c.PyNumberMethods)\* `tp_as_number`**223224Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих числовой протокол. Эти поля описаны в [Структуры числовых объектов](https://python-all.ru/2.7/c-api/typeobj.html#number-structs).225226Поле `tp_as_number` не наследуется, но содержащиеся в нём поля наследуются по отдельности.227228**[PySequenceMethods](https://python-all.ru/2.7/c-api/typeobj.html#c.PySequenceMethods)\* `tp_as_sequence`**229230Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол последовательности. Эти поля описаны в [Структуры объектов-последовательностей](https://python-all.ru/2.7/c-api/typeobj.html#sequence-structs).231232Поле `tp_as_sequence` не наследуется, но содержащиеся в нём поля наследуются по отдельности.233234**[PyMappingMethods](https://python-all.ru/2.7/c-api/typeobj.html#c.PyMappingMethods)\* `tp_as_mapping`**235236Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол отображения. Эти поля описаны в [Структуры объектов-отображений](https://python-all.ru/2.7/c-api/typeobj.html#mapping-structs).237238Поле `tp_as_mapping` не наследуется, но содержащиеся в нём поля наследуются по отдельности.239240**hashfunc `PyTypeObject.tp_hash`**241242Необязательный указатель на функцию, реализующую встроенную функцию [`hash()`](https://python-all.ru/2.7/library/functions.html#hash).243244Сигнатура такая же, как у [`PyObject_Hash()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Hash); она должна возвращать C long. Значение `-1` не должно возвращаться как обычное возвращаемое значение; при возникновении ошибки во время вычисления хеш-значения функция должна установить исключение и вернуть `-1`.245246Это поле можно явно установить в [`PyObject_HashNotImplemented()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_HashNotImplemented), чтобы заблокировать наследование хеш-метода от родительского типа. Это интерпретируется как эквивалент `__hash__ = None` на уровне Python, в результате чего `isinstance(o, collections.Hashable)` корректно возвращает `False`. Обратите внимание, что верно и обратное: установка `__hash__ = None` в классе на уровне Python приведет к тому, что слот `tp_hash` будет установлен в [`PyObject_HashNotImplemented()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_HashNotImplemented).247248Если это поле не установлено, возможны два варианта: если поля [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare) и [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) оба равны *NULL*, возвращается значение хеша по умолчанию на основе адреса объекта; в противном случае возбуждается [`TypeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.TypeError).249250Это поле наследуется подтипами вместе с [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare): подтип наследует все три [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare), [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_hash), когда поля [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare), [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа все равны *NULL*.251252**ternaryfunc `PyTypeObject.tp_call`**253254Необязательный указатель на функцию, которая реализует вызов объекта. Это должен быть *NULL*, если объект не является вызываемым. Сигнатура такая же, как у [`PyObject_Call()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Call).255256Это поле наследуется подтипами.257258**reprfunc `PyTypeObject.tp_str`**259260Необязательный указатель на функцию, реализующую встроенную операцию [`str()`](https://python-all.ru/2.7/library/functions.html#str). (Обратите внимание, что [`str`](https://python-all.ru/2.7/library/functions.html#str) теперь является типом, а [`str()`](https://python-all.ru/2.7/library/functions.html#str) вызывает конструктор этого типа. Этот конструктор вызывает [`PyObject_Str()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Str) для выполнения фактической работы, и [`PyObject_Str()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Str) будет вызывать этот обработчик.)261262Сигнатура такая же, как у [`PyObject_Str()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Str); функция должна возвращать строку или объект Unicode. Эта функция должна возвращать «дружественное» строковое представление объекта, поскольку именно это представление будет использоваться оператором print.263264Если это поле не задано, вызывается [`PyObject_Repr()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Repr) для возврата строкового представления.265266Это поле наследуется подтипами.267268**getattrofunc `PyTypeObject.tp_getattro`**269270Необязательный указатель на функцию получения атрибута.271272Сигнатура такая же, как у [`PyObject_GetAttr()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_GetAttr). Обычно удобно устанавливать это поле в [`PyObject_GenericGetAttr()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_GenericGetAttr), которое реализует обычный способ поиска атрибутов объекта.273274Это поле наследуется подтипами вместе с [`tp_getattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr): подтип наследует как [`tp_getattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr), так и [`tp_getattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr) и [`tp_getattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) подтипа оба равны *NULL*.275276**setattrofunc `PyTypeObject.tp_setattro`**277278Необязательный указатель на функцию для установки и удаления атрибутов.279280Сигнатура такая же, как у [`PyObject_SetAttr()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_SetAttr), но необходимо поддерживать установку *v* в *NULL* для удаления атрибута. Обычно удобно установить это поле в [`PyObject_GenericSetAttr()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_GenericSetAttr), которое реализует обычный способ установки атрибутов объектов.281282Это поле наследуется подтипами вместе с [`tp_setattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr): подтип наследует как [`tp_setattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr), так и [`tp_setattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro) от своего базового типа, когда [`tp_setattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr) и [`tp_setattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro) подтипа оба равны *NULL*.283284**[PyBufferProcs](https://python-all.ru/2.7/c-api/typeobj.html#c.PyBufferProcs)\* `PyTypeObject.tp_as_buffer`**285286Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих буферный интерфейс. Эти поля описаны в [Buffer Object Structures](https://python-all.ru/2.7/c-api/typeobj.html#buffer-structs).287288Поле [`tp_as_buffer`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer) не наследуется, но содержащиеся в нём поля наследуются по отдельности.289290**long `PyTypeObject.tp_flags`**291292Это поле представляет собой битовую маску различных флагов. Некоторые флаги указывают на вариантную семантику для определённых ситуаций; другие используются для обозначения того, что определённые поля в объекте типа (или в структурах расширения, на которые ссылаются через `tp_as_number`, `tp_as_sequence`, `tp_as_mapping` и [`tp_as_buffer`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer)), которые исторически присутствовали не всегда, являются корректными; если такой бит флага сброшен, то поля типа, которые он защищает, нельзя использовать, и они считаются имеющими нулевое значение или *NULL*.293294Наследование этого поля сложное. Большинство битовых флагов наследуются по отдельности: если флаг установлен в базовом типе, подтип наследует этот флаг. Флаги, относящиеся к структурам расширения, наследуются строго, если наследуется сама структура расширения, то есть значение флага базового типа копируется в подтип вместе с указателем на структуру расширения. Бит [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) наследуется вместе с полями [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear): то есть если бит [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) сброшен в подтипе, а поля [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) в подтипе существуют (как указывает бит [`Py_TPFLAGS_HAVE_RICHCOMPARE`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_RICHCOMPARE)) и имеют значения *NULL*.295296В настоящее время определены следующие битовые маски; их можно объединять с помощью оператора `|` для получения значения поля [`tp_flags`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_flags). Макрос [`PyType_HasFeature()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_HasFeature) принимает тип и значение флагов, *tp* и *f*, и проверяет, является ли `tp->tp_flags & f` ненулевым.297298#### `Py_TPFLAGS_HAVE_GETCHARBUFFER`299300Если этот бит установлен, структура [`PyBufferProcs`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyBufferProcs), на которую ссылается [`tp_as_buffer`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer), содержит поле `bf_getcharbuffer`.301302#### `Py_TPFLAGS_HAVE_SEQUENCE_IN`303304Если этот бит установлен, структура [`PySequenceMethods`](https://python-all.ru/2.7/c-api/typeobj.html#c.PySequenceMethods), на которую ссылается `tp_as_sequence`, содержит поле `sq_contains`.305306#### `Py_TPFLAGS_GC`307308Этот бит устарел. Бит, который он обозначал, больше не используется. Символ теперь определяется как ноль.309310#### `Py_TPFLAGS_HAVE_INPLACEOPS`311312Если этот бит установлен, структура [`PySequenceMethods`](https://python-all.ru/2.7/c-api/typeobj.html#c.PySequenceMethods), на которую ссылается `tp_as_sequence`, и структура [`PyNumberMethods`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyNumberMethods), на которую ссылается `tp_as_number`, содержат поля для операций на месте (in-place). В частности, это означает, что структура [`PyNumberMethods`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyNumberMethods) имеет поля `nb_inplace_add`, `nb_inplace_subtract`, `nb_inplace_multiply`, `nb_inplace_divide`, `nb_inplace_remainder`, `nb_inplace_power`, `nb_inplace_lshift`, `nb_inplace_rshift`, `nb_inplace_and`, `nb_inplace_xor` и `nb_inplace_or`; а структура [`PySequenceMethods`](https://python-all.ru/2.7/c-api/typeobj.html#c.PySequenceMethods) имеет поля `sq_inplace_concat` и `sq_inplace_repeat`.313314#### `Py_TPFLAGS_CHECKTYPES`315316Если этот бит установлен, бинарные и тернарные операции в структуре [`PyNumberMethods`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyNumberMethods), на которую ссылается `tp_as_number`, принимают аргументы произвольных типов объектов и выполняют собственное преобразование типов при необходимости. Если этот бит сброшен, такие операции требуют, чтобы все аргументы имели текущий тип, и вызывающий должен сначала выполнить приведение (coercion). Это относится к `nb_add`, `nb_subtract`, `nb_multiply`, `nb_divide`, `nb_remainder`, `nb_divmod`, `nb_power`, `nb_lshift`, `nb_rshift`, `nb_and`, `nb_xor` и `nb_or`.317318#### `Py_TPFLAGS_HAVE_RICHCOMPARE`319320Если этот бит установлен, объект типа имеет поля [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare), [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear).321322#### `Py_TPFLAGS_HAVE_WEAKREFS`323324Если этот бит установлен, поле [`tp_weaklistoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) определено. Экземпляры типа могут быть слабо ссылаемыми, если поле [`tp_weaklistoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) типа имеет значение больше нуля.325326#### `Py_TPFLAGS_HAVE_ITER`327328Если этот бит установлен, объект типа имеет поля [`tp_iter`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_iter) и [`tp_iternext`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_iternext).329330#### `Py_TPFLAGS_HAVE_CLASS`331332Если этот бит установлен, объект типа имеет несколько новых полей, определенных начиная с Python 2.2: [`tp_methods`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_methods), [`tp_members`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_members), [`tp_getset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getset), [`tp_base`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_base), [`tp_dict`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dict), [`tp_descr_get`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_descr_get), [`tp_descr_set`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_descr_set), [`tp_dictoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset), [`tp_init`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_init), [`tp_alloc`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_alloc), [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new), [`tp_free`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_free), [`tp_is_gc`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_is_gc), [`tp_bases`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_bases), [`tp_mro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_mro), [`tp_cache`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_cache), [`tp_subclasses`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_subclasses) и [`tp_weaklist`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklist).333334#### `Py_TPFLAGS_HEAPTYPE`335336Этот бит устанавливается, когда сам объект типа выделяется в куче. В таком случае поле `ob_type` его экземпляров считается ссылкой на тип, и счётчик ссылок объекта типа увеличивается (INCREF) при создании нового экземпляра и уменьшается (DECREF) при уничтожении экземпляра (это не относится к экземплярам подтипов; только тип, на который ссылается ob\_type экземпляра, получает INCREF или DECREF).337338#### `Py_TPFLAGS_BASETYPE`339340Этот бит устанавливается, когда тип может использоваться как базовый тип другого типа. Если этот бит сброшен, тип не может быть унаследован (аналогично «финальному» классу в Java).341342#### `Py_TPFLAGS_READY`343344Этот бит устанавливается, когда объект типа был полностью инициализирован функцией [`PyType_Ready()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Ready).345346#### `Py_TPFLAGS_READYING`347348Этот бит устанавливается, пока [`PyType_Ready()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Ready) находится в процессе инициализации объекта типа.349350#### `Py_TPFLAGS_HAVE_GC`351352Этот бит установлен, если объект поддерживает сборку мусора. Если этот бит установлен, экземпляры должны создаваться с помощью [`PyObject_GC_New()`](https://python-all.ru/2.7/c-api/gcsupport.html#c.PyObject_GC_New) и уничтожаться с помощью [`PyObject_GC_Del()`](https://python-all.ru/2.7/c-api/gcsupport.html#c.PyObject_GC_Del). Подробнее в разделе [Поддержка циклической сборки мусора](https://python-all.ru/2.7/c-api/gcsupport.html#supporting-cycle-detection). Этот бит также означает, что связанные со сборкой мусора поля [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) присутствуют в объекте типа; но эти поля также существуют, когда [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) сброшен, а [`Py_TPFLAGS_HAVE_RICHCOMPARE`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_RICHCOMPARE) установлен.353354#### `Py_TPFLAGS_DEFAULT`355356Это битовая маска всех битов, относящихся к наличию определенных полей в объекте типа и его структурах расширения. В настоящее время она включает следующие биты: [`Py_TPFLAGS_HAVE_GETCHARBUFFER`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GETCHARBUFFER), [`Py_TPFLAGS_HAVE_SEQUENCE_IN`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_SEQUENCE_IN), [`Py_TPFLAGS_HAVE_INPLACEOPS`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_INPLACEOPS), [`Py_TPFLAGS_HAVE_RICHCOMPARE`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_RICHCOMPARE), [`Py_TPFLAGS_HAVE_WEAKREFS`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_WEAKREFS), [`Py_TPFLAGS_HAVE_ITER`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_ITER) и [`Py_TPFLAGS_HAVE_CLASS`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_CLASS).357358**char\* `PyTypeObject.tp_doc`**359360Необязательный указатель на C-строку, завершающуюся нулевым символом, содержащую строку документации для этого объекта типа. Это отображается как атрибут `__doc__` у типа и его экземпляров.361362Это поле *не* наследуется подтипами.363364Следующие три поля существуют только если установлен бит флага [`Py_TPFLAGS_HAVE_RICHCOMPARE`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_RICHCOMPARE).365366**[traverseproc](https://python-all.ru/2.7/c-api/gcsupport.html#c.traverseproc) `PyTypeObject.tp_traverse`**367368Необязательный указатель на функцию обхода для сборщика мусора. Используется только если установлен флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Дополнительную информацию о схеме сборки мусора Python можно найти в разделе [Поддержка циклической сборки мусора](https://python-all.ru/2.7/c-api/gcsupport.html#supporting-cycle-detection).369370Указатель [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) используется сборщиком мусора для обнаружения циклических ссылок. Типичная реализация функции [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) просто вызывает [`Py_VISIT()`](https://python-all.ru/2.7/c-api/gcsupport.html#c.Py_VISIT) для каждого из членов экземпляра, являющегося объектом Python. Например, такова функция `local_traverse()` из модуля расширения [`thread`](https://python-all.ru/2.7/library/thread.html#module-thread):371372```c373static int374local_traverse(localobject *self, visitproc visit, void *arg)375{376 Py_VISIT(self->args);377 Py_VISIT(self->kw);378 Py_VISIT(self->dict);379 return 0;380}381```382383Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/2.7/c-api/gcsupport.html#c.Py_VISIT) вызывается только для тех членов, которые могут участвовать в циклических ссылках. Хотя существует и член `self->key`, он может быть только *NULL* или строкой Python, а потому не может быть частью циклической ссылки.384385С другой стороны, даже если известно, что член никогда не может быть частью цикла, в качестве средства отладки его всё равно можно обойти, чтобы функция [`get_referents()`](https://python-all.ru/2.7/library/gc.html#gc.get_referents) модуля [`gc`](https://python-all.ru/2.7/library/gc.html#module-gc) включила его.386387Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/2.7/c-api/gcsupport.html#c.Py_VISIT) требует, чтобы параметры *visit* и *arg* для `local_traverse()` имели именно такие имена; не следует называть их как попало.388389Это поле наследуется подтипами вместе с [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) и битом флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): бит флага, [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) наследуются от базового типа, если в подтипе они все равны нулю *и* в подтипе установлен бит флага [`Py_TPFLAGS_HAVE_RICHCOMPARE`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_RICHCOMPARE).390391**[inquiry](https://python-all.ru/2.7/c-api/gcsupport.html#c.inquiry) `PyTypeObject.tp_clear`**392393Необязательный указатель на функцию очистки для сборщика мусора. Используется только если установлен флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).394395Функция-член [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) используется для разрыва циклических ссылок в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности все функции [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) в системе должны совместно разрывать все циклические ссылки. Это тонкий момент, и при любых сомнениях следует предоставить функцию [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear). Например, тип tuple не реализует функцию [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear), поскольку можно доказать, что ни одна циклическая ссылка не может состоять исключительно из кортежей. Поэтому функции [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) других типов должны быть достаточны для разрыва любой циклической ссылки, содержащей кортеж. Это не очевидно, и редко есть веская причина избегать реализации [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear).396397Реализации [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) должны освобождать ссылки экземпляра на те его члены, которые могут быть объектами Python, и устанавливать указатели на эти члены в *NULL*, как в следующем примере:398399```c400static int401local_clear(localobject *self)402{403 Py_CLEAR(self->key);404 Py_CLEAR(self->args);405 Py_CLEAR(self->kw);406 Py_CLEAR(self->dict);407 return 0;408}409```410411Следует использовать макрос [`Py_CLEAR()`](https://python-all.ru/2.7/c-api/refcounting.html#c.Py_CLEAR), потому что очистка ссылок – дело тонкое: счётчик ссылок на содержащийся объект не должен уменьшаться до тех пор, пока указатель на этот объект не будет установлен в *NULL*. Это связано с тем, что уменьшение счётчика ссылок может привести к тому, что содержащийся объект станет мусором, что вызовет цепочку действий по его освобождению, которая может включать выполнение произвольного кода Python (из-за финализаторов или колбэков слабых ссылок, связанных с содержащимся объектом). Если такой код может снова обратиться к *self*, важно, чтобы указатель на содержащийся объект в этот момент был *NULL*, чтобы *self* знал, что содержащийся объект больше нельзя использовать. Макрос [`Py_CLEAR()`](https://python-all.ru/2.7/c-api/refcounting.html#c.Py_CLEAR) выполняет операции в безопасном порядке.412413Поскольку цель функций [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) – разрывать циклические ссылки, нет необходимости очищать содержащиеся объекты, такие как строки Python или целые числа Python, которые не могут участвовать в циклических ссылках. С другой стороны, может быть удобно очистить все содержащиеся объекты Python и написать функцию [`tp_dealloc`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dealloc) типа так, чтобы она вызывала [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear).414415Дополнительную информацию о схеме сборки мусора Python можно найти в разделе [Поддержка циклической сборки мусора](https://python-all.ru/2.7/c-api/gcsupport.html#supporting-cycle-detection).416417Это поле наследуется подтипами вместе с [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и битом флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): бит флага, [`tp_traverse`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) наследуются от базового типа, если в подтипе они все равны нулю *и* в подтипе установлен бит флага [`Py_TPFLAGS_HAVE_RICHCOMPARE`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_RICHCOMPARE).418419**richcmpfunc `PyTypeObject.tp_richcompare`**420421Необязательный указатель на функцию расширенного сравнения (rich comparison), сигнатура которой – `PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)`.422423Функция должна возвращать результат сравнения (обычно `Py_True` или `Py_False`). Если сравнение не определено, она должна вернуть `Py_NotImplemented`; если произошла другая ошибка, она должна вернуть `NULL` и установить условие исключения.424425> **Примечание**426>427> Если требуется реализовать тип, для которого имеет смысл только ограниченный набор сравнений (например, `==` и `!=`, но не `<` и др.), следует напрямую возбуждать [`TypeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.TypeError) в функции расширенного сравнения.428429Это поле наследуется подтипами вместе с [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare) и [`tp_hash`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_hash): подтип наследует все три [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare), [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_hash), когда поля [`tp_compare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_compare), [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа все равны *NULL*.430431Следующие константы определены для использования в качестве третьего аргумента для [`tp_richcompare`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и для [`PyObject_RichCompare()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_RichCompare):432433| Константа | Сравнение |434| --- | --- |435| `Py_LT` | `<` |436| `Py_LE` | `<=` |437| `Py_EQ` | `==` |438| `Py_NE` | `!=` |439| `Py_GT` | `>` |440| `Py_GE` | `>=` |441442Следующее поле существует только если установлен бит флага [`Py_TPFLAGS_HAVE_WEAKREFS`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_WEAKREFS).443444**long `PyTypeObject.tp_weaklistoffset`**445446Если экземпляры этого типа могут использоваться в слабых ссылках, это поле больше нуля и содержит смещение в структуре экземпляра до головы списка слабых ссылок (игнорируя заголовок GC, если он присутствует); это смещение используется функциями `PyObject_ClearWeakRefs()` и `PyWeakref_*()`. Структура экземпляра должна содержать поле типа [`PyObject*`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject), инициализированное значением *NULL*.447448Не путайте это поле с [`tp_weaklist`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklist); это голова списка для слабых ссылок на сам объект типа.449450Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что подтип использует другую голову списка слабых ссылок, нежели базовый тип. Поскольку голова списка всегда находится через [`tp_weaklistoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset), это не должно быть проблемой.451452Если тип, определённый с помощью оператора class, не содержит объявления `__slots__`, и ни один из его базовых типов не поддерживает слабые ссылки, тип делается доступным для слабых ссылок: в компоновку экземпляра добавляется слот заголовка списка слабых ссылок, и [`tp_weaklistoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) устанавливается на смещение этого слота.453454Если объявление [`__slots__`](https://python-all.ru/2.7/reference/datamodel.html#__slots__) типа содержит слот с именем `__weakref__`, этот слот становится заголовком списка слабых ссылок для экземпляров типа, а его смещение сохраняется в поле [`tp_weaklistoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) типа.455456Если объявление [`__slots__`](https://python-all.ru/2.7/reference/datamodel.html#__slots__) типа не содержит слота с именем `__weakref__`, тип наследует значение [`tp_weaklistoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) от своего базового типа.457458Следующие два поля существуют только если установлен бит флага [`Py_TPFLAGS_HAVE_ITER`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_ITER).459460**getiterfunc `PyTypeObject.tp_iter`**461462Необязательный указатель на функцию, возвращающую итератор для объекта. Его наличие обычно означает, что экземпляры этого типа являются итерируемыми (хотя последовательности могут быть итерируемыми и без этой функции, а экземпляры классических классов всегда имеют эту функцию, даже если не определяют метод [`__iter__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__iter__)).463464Эта функция имеет ту же сигнатуру, что и [`PyObject_GetIter()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_GetIter).465466Это поле наследуется подтипами.467468**iternextfunc `PyTypeObject.tp_iternext`**469470Необязательный указатель на функцию, возвращающую следующий элемент итератора. Когда итератор исчерпан, она должна вернуть *NULL*; исключение [`StopIteration`](https://python-all.ru/2.7/library/exceptions.html#exceptions.StopIteration) может быть установлено или не установлено. При возникновении другой ошибки она также должна вернуть *NULL*. Его наличие обычно означает, что экземпляры этого типа являются итераторами (хотя экземпляры классических классов всегда имеют эту функцию, даже если не определяют метод [`next()`](https://python-all.ru/2.7/library/stdtypes.html#iterator.next)).471472Типы-итераторы также должны определять функцию [`tp_iter`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_iter), и эта функция должна возвращать сам экземпляр итератора (не новый экземпляр итератора).473474Эта функция имеет ту же сигнатуру, что и [`PyIter_Next()`](https://python-all.ru/2.7/c-api/iter.html#c.PyIter_Next).475476Это поле наследуется подтипами.477478Следующие поля, вплоть до [`tp_weaklist`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklist) включительно, существуют только если установлен бит флага [`Py_TPFLAGS_HAVE_CLASS`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_CLASS).479480**struct [PyMethodDef](https://python-all.ru/2.7/c-api/structures.html#c.PyMethodDef)\* `PyTypeObject.tp_methods`**481482Необязательный указатель на статический массив структур [`PyMethodDef`](https://python-all.ru/2.7/c-api/structures.html#c.PyMethodDef), завершающийся *NULL*, объявляющий обычные методы этого типа.483484Для каждой записи в массиве в словарь типа добавляется запись (см. [`tp_dict`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже), содержащая дескриптор метода.485486Это поле не наследуется подтипами (методы наследуются через другой механизм).487488**struct [PyMemberDef](https://python-all.ru/2.7/c-api/structures.html#c.PyMemberDef)\* `PyTypeObject.tp_members`**489490Необязательный указатель на статический массив структур [`PyMemberDef`](https://python-all.ru/2.7/c-api/structures.html#c.PyMemberDef), завершающийся *NULL*, объявляющий обычные элементы данных (поля или слоты) экземпляров этого типа.491492Для каждой записи в массиве в словарь типа добавляется запись, содержащая дескриптор члена (см. [`tp_dict`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже).493494Это поле не наследуется подтипами (члены наследуются через другой механизм).495496**struct [PyGetSetDef](https://python-all.ru/2.7/c-api/structures.html#c.PyGetSetDef)\* `PyTypeObject.tp_getset`**497498Необязательный указатель на статический массив структур [`PyGetSetDef`](https://python-all.ru/2.7/c-api/structures.html#c.PyGetSetDef), завершающийся *NULL*, объявляющий вычисляемые атрибуты экземпляров этого типа.499500Для каждой записи в массиве в словарь типа добавляется запись, содержащая дескриптор getset (см. [`tp_dict`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже).501502Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).503504**[PyTypeObject](https://python-all.ru/2.7/c-api/type.html#c.PyTypeObject)\* `PyTypeObject.tp_base`**505506Необязательный указатель на базовый тип, от которого наследуются свойства типа. На этом уровне поддерживается только одиночное наследование; множественное наследование требует динамического создания объекта типа вызовом метатипа.507508Это поле не наследуется подтипами (очевидно), но по умолчанию оно равно `&PyBaseObject_Type` (которое программистам Python известно как тип [`object`](https://python-all.ru/2.7/library/functions.html#object)).509510**[PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_dict`**511512Словарь типа сохраняется здесь с помощью [`PyType_Ready()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Ready).513514Обычно это поле следует инициализировать значением *NULL* до вызова PyType\_Ready; его также можно инициализировать словарём, содержащим начальные атрибуты типа. После того как [`PyType_Ready()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Ready) инициализирует тип, в этот словарь можно добавлять дополнительные атрибуты типа только в том случае, если они не соответствуют перегруженным операциям (например, [`__add__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__add__)).515516Это поле не наследуется подтипами (хотя определённые здесь атрибуты наследуются через другой механизм).517518**descrgetfunc `PyTypeObject.tp_descr_get`**519520Необязательный указатель на функцию «descriptor get».521522Сигнатура функции:523524```c525PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);526```527528Это поле наследуется подтипами.529530**descrsetfunc `PyTypeObject.tp_descr_set`**531532Необязательный указатель на функцию для установки и удаления значения дескриптора.533534Сигнатура функции:535536```c537int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);538```539540Аргумент *value* устанавливается в *NULL* для удаления значения. Это поле наследуется подтипами.541542**long `PyTypeObject.tp_dictoffset`**543544Если экземпляры этого типа имеют словарь, содержащий переменные экземпляра, это поле не равно нулю и содержит смещение в структуре экземпляра для словаря переменных экземпляра; это смещение используется [`PyObject_GenericGetAttr()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_GenericGetAttr).545546Не путайте это поле с [`tp_dict`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dict); это словарь для атрибутов самого объекта типа.547548Если значение этого поля больше нуля, оно задаёт смещение от начала структуры экземпляра. Если значение меньше нуля, оно задаёт смещение от *конца* структуры экземпляра. Использование отрицательного смещения обходится дороже, и его следует применять только в тех случаях, когда структура экземпляра содержит часть переменной длины. Это используется, например, для добавления словаря переменных экземпляра в подтипы [`str`](https://python-all.ru/2.7/library/functions.html#str) или [`tuple`](https://python-all.ru/2.7/library/functions.html#tuple). Обратите внимание, что поле [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) должно учитывать словарь, добавленный в конец в этом случае, даже если словарь не входит в базовую компоновку объекта. В системе с размером указателя 4 байта [`tp_dictoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) должно быть установлено в `-4`, чтобы указать, что словарь находится в самом конце структуры.549550Реальное смещение словаря в экземпляре можно вычислить из отрицательного [`tp_dictoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) следующим образом:551552```c553dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset554if dictoffset is not aligned on sizeof(void*):555 round up to sizeof(void*)556```557558где [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize), [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) и [`tp_dictoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) берутся из объекта типа, а `ob_size` – из экземпляра. Берётся абсолютное значение, потому что длинные целые используют знак `ob_size` для хранения знака числа. (Никогда не нужно выполнять это вычисление самостоятельно; за вас это делает `_PyObject_GetDictPtr()`.)559560Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что экземпляры подтипа хранят словарь по другому смещению, нежели базовый тип. Поскольку словарь всегда находится через [`tp_dictoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset), это не должно вызывать проблем.561562Если тип, определённый с помощью оператора class, не содержит объявления `__slots__`, и ни один из его базовых типов не имеет словаря переменных экземпляра, в компоновку экземпляра добавляется слот словаря, а [`tp_dictoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) устанавливается на смещение этого слота.563564Если тип, определённый с помощью оператора class, содержит объявление [`__slots__`](https://python-all.ru/2.7/reference/datamodel.html#__slots__), тот тип наследует значение [`tp_dictoffset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) от своего базового типа.565566(Добавление слота с именем [`__dict__`](https://python-all.ru/2.7/library/stdtypes.html#object.__dict__) в объявление [`__slots__`](https://python-all.ru/2.7/reference/datamodel.html#__slots__) не даёт ожидаемого эффекта, а только вызывает путаницу. Возможно, эту возможность стоит добавить как отдельную функцию, подобно `__weakref__`.)567568**initproc `PyTypeObject.tp_init`**569570Необязательный указатель на функцию инициализации экземпляра.571572Эта функция соответствует методу [`__init__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__init__) классов. Как и [`__init__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__init__), можно создать экземпляр без вызова [`__init__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__init__), и можно переинициализировать экземпляр, вызвав его метод [`__init__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__init__) ещё раз.573574Сигнатура функции:575576```c577int tp_init(PyObject *self, PyObject *args, PyObject *kwds)578```579580Аргумент self – это инициализируемый экземпляр; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова [`__init__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__init__).581582Функция [`tp_init`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_init), если не *NULL*, вызывается при обычном создании экземпляра путём вызова его типа, после того как функция [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new) типа вернула экземпляр этого типа. Если функция [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new) возвращает экземпляр другого типа, не являющегося подтипом исходного типа, функция [`tp_init`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_init) не вызывается; если [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new) возвращает экземпляр подтипа исходного типа, вызывается [`tp_init`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_init) подтипа. (ПРИМЕЧАНИЕ ПО ВЕРСИЯМ: здесь описано то, что реализовано в Python 2.2.1 и новее. В Python 2.2 всегда вызывался [`tp_init`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_init) типа объекта, возвращаемого [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new), если не *NULL*.)583584Это поле наследуется подтипами.585586**allocfunc `PyTypeObject.tp_alloc`**587588Необязательный указатель на функцию выделения экземпляра.589590Сигнатура функции:591592```c593PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)594```595596Назначение этой функции – разделить выделение памяти и её инициализацию. Она должна возвращать указатель на блок памяти достаточной длины для экземпляра, с подходящим выравниванием и обнулённый, но с `ob_refcnt`, установленным в `1`, и `ob_type`, установленным в аргумент типа. Если [`tp_itemsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) типа не равно нулю, поле `ob_size` объекта должно быть инициализировано значением *nitems*, а длина выделенного блока памяти должна быть `tp_basicsize + nitems*tp_itemsize`, округлённой до кратного `sizeof(void*)`; в противном случае *nitems* не используется, и длина блока должна быть [`tp_basicsize`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).597598Эту функцию не следует использовать для какой-либо другой инициализации экземпляра, в том числе для выделения дополнительной памяти; это должно выполняться с помощью [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new).599600Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными выражением class); в последних это поле всегда устанавливается в [`PyType_GenericAlloc()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_GenericAlloc), чтобы принудительно использовать стандартную стратегию выделения в куче. Это также рекомендуемое значение для статически определённых типов.601602**newfunc `PyTypeObject.tp_new`**603604Необязательный указатель на функцию создания экземпляра.605606Если для данного типа эта функция равна *NULL*, то этот тип нельзя вызвать для создания новых экземпляров; предполагается, что существует другой способ создания экземпляров, например, фабричная функция.607608Сигнатура функции:609610```c611PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)612```613614Аргумент subtype – это тип создаваемого объекта; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова типа. Обратите внимание, что subtype не обязан совпадать с типом, для которого вызывается функция [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new); это может быть подтип этого типа (но не произвольный тип).615616Функция [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new) должна вызывать `subtype->tp_alloc(subtype, nitems)` для выделения памяти под объект, а затем выполнять лишь минимально необходимую инициализацию. Инициализацию, которую можно безопасно пропустить или повторить, следует помещать в обработчик [`tp_init`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_init). Хорошее эмпирическое правило: для неизменяемых типов вся инициализация должна выполняться в [`tp_new`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_new), а для изменяемых типов большую часть инициализации лучше отложить до [`tp_init`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_init).617618Это поле наследуется подтипами, за исключением статических типов, у которых [`tp_base`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_base) равно *NULL* или `&PyBaseObject_Type`. Последнее исключение сделано в целях предосторожности, чтобы старые типы расширений не становились вызываемыми просто из-за связывания с Python 2.2.619620**destructor `PyTypeObject.tp_free`**621622Необязательный указатель на функцию освобождения экземпляра.623624Сигнатура этой функции немного изменилась: в Python 2.2 и 2.2.1 её сигнатура – `destructor`:625626```c627void tp_free(PyObject *)628```629630В Python 2.3 и новее её сигнатура – `freefunc`:631632```c633void tp_free(void *)634```635636Единственный инициализатор, совместимый с обеими версиями, – это `_PyObject_Del`, чьё определение было соответствующим образом адаптировано в Python 2.3.637638Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными выражением class); в последних это поле устанавливается в освободитель, подходящий для [`PyType_GenericAlloc()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_GenericAlloc) и значения бита флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).639640**[inquiry](https://python-all.ru/2.7/c-api/gcsupport.html#c.inquiry) `PyTypeObject.tp_is_gc`**641642Необязательный указатель на функцию, вызываемую сборщиком мусора.643644Сборщику мусора необходимо знать, подлежит ли данный объект сборке или нет. Обычно достаточно посмотреть на поле [`tp_flags`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_flags) типа объекта и проверить бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Но некоторые типы имеют смесь статически и динамически выделенных экземпляров, причём статически выделенные экземпляры не подлежат сборке. Таким типам следует определить эту функцию; она должна возвращать `1` для собираемого экземпляра и `0` для несобираемого. Сигнатура:645646```c647int tp_is_gc(PyObject *self)648```649650(Единственный пример этого – сами типы. Метатип, [`PyType_Type`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Type), определяет эту функцию, чтобы различать статически и динамически выделенные типы.)651652Это поле наследуется подтипами. (ПРИМЕЧАНИЕ ПО ВЕРСИЯМ: в Python 2.2 оно не наследовалось. Оно наследуется в 2.2.1 и более новых версиях.)653654**[PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_bases`**655656Кортеж базовых типов.657658Это устанавливается для типов, созданных с помощью оператора class. Для статически определённых типов оно должно быть равно *NULL*.659660Это поле не наследуется.661662**[PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_mro`**663664Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая [`object`](https://python-all.ru/2.7/library/functions.html#object), в порядке разрешения методов (MRO).665666Это поле не наследуется; оно вычисляется заново с помощью [`PyType_Ready()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_Ready).667668**[PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_cache`**669670Не используется. Не наследуется. Только для внутреннего использования.671672**[PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_subclasses`**673674Список слабых ссылок на подклассы. Не наследуется. Только для внутреннего использования.675676**[PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_weaklist`**677678Голова списка слабых ссылок для слабых ссылок на этот объект типа. Не наследуется. Только для внутреннего использования.679680Остальные поля определены только если определён макрос проверки возможностей `COUNT_ALLOCS` и предназначены только для внутреннего использования. Они dокументированы здесь для полноты. Ни одно из этих полей не наследуется подтипами. См. переменную окружения [`PYTHONSHOWALLOCCOUNT`](https://python-all.ru/2.7/using/cmdline.html#envvar-PYTHONSHOWALLOCCOUNT).681682**Py\_ssize\_t `PyTypeObject.tp_allocs`**683684Количество выделений памяти.685686**Py\_ssize\_t `PyTypeObject.tp_frees`**687688Количество освобождений.689690**Py\_ssize\_t `PyTypeObject.tp_maxalloc`**691692Максимальное количество одновременно выделенных объектов.693694**[PyTypeObject](https://python-all.ru/2.7/c-api/type.html#c.PyTypeObject)\* `PyTypeObject.tp_next`**695696Указатель на следующий объект типа с ненулевым полем [`tp_allocs`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_allocs).697698Также следует отметить, что в Python со сборкой мусора tp\_dealloc может вызываться из любого потока Python, а не только из того, который создал объект (если объект становится частью цикла подсчёта ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Это не проблема для вызовов Python API, поскольку поток, в котором вызывается tp\_dealloc, будет владеть глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект, в свою очередь, уничтожает объекты из какой-либо другой библиотеки C или C++, следует соблюдать осторожность, чтобы убедиться, что уничтожение этих объектов в потоке, вызвавшем tp\_dealloc, не нарушит никаких предположений библиотеки.699700# Структуры числовых объектов701702**`PyNumberMethods`**703704Эта структура содержит указатели на функции, которые объект использует для реализации числового протокола. Почти каждая из перечисленных ниже функций используется одноимённой функцией, описанной в разделе [Числовой протокол](https://python-all.ru/2.7/c-api/number.html#number).705706Вот определение структуры:707708```c709typedef struct {710 binaryfunc nb_add;711 binaryfunc nb_subtract;712 binaryfunc nb_multiply;713 binaryfunc nb_divide;714 binaryfunc nb_remainder;715 binaryfunc nb_divmod;716 ternaryfunc nb_power;717 unaryfunc nb_negative;718 unaryfunc nb_positive;719 unaryfunc nb_absolute;720 inquiry nb_nonzero; /* Используется PyObject_IsTrue */721 unaryfunc nb_invert;722 binaryfunc nb_lshift;723 binaryfunc nb_rshift;724 binaryfunc nb_and;725 binaryfunc nb_xor;726 binaryfunc nb_or;727 coercion nb_coerce; /* Используется функцией coerce() */728 unaryfunc nb_int;729 unaryfunc nb_long;730 unaryfunc nb_float;731 unaryfunc nb_oct;732 unaryfunc nb_hex;733734 /* Добавлено в версии 2.0 */735 binaryfunc nb_inplace_add;736 binaryfunc nb_inplace_subtract;737 binaryfunc nb_inplace_multiply;738 binaryfunc nb_inplace_divide;739 binaryfunc nb_inplace_remainder;740 ternaryfunc nb_inplace_power;741 binaryfunc nb_inplace_lshift;742 binaryfunc nb_inplace_rshift;743 binaryfunc nb_inplace_and;744 binaryfunc nb_inplace_xor;745 binaryfunc nb_inplace_or;746747 /* Добавлено в версии 2.2 */748 binaryfunc nb_floor_divide;749 binaryfunc nb_true_divide;750 binaryfunc nb_inplace_floor_divide;751 binaryfunc nb_inplace_true_divide;752753 /* Добавлено в версии 2.5 */754 unaryfunc nb_index;755} PyNumberMethods;756```757758Бинарные и тернарные функции могут получать аргументы разных видов в зависимости от бита флага [`Py_TPFLAGS_CHECKTYPES`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_CHECKTYPES):759760- Если [`Py_TPFLAGS_CHECKTYPES`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_CHECKTYPES) не установлен, гарантируется, что аргументы функции принадлежат типу объекта; вызывающая сторона отвечает за вызов метода приведения, заданного членом `nb_coerce`, для преобразования аргументов:761762 **coercion `PyNumberMethods.nb_coerce`**763764 Эта функция используется в [`PyNumber_CoerceEx()`](https://python-all.ru/2.7/c-api/number.html#c.PyNumber_CoerceEx) и имеет ту же сигнатуру. Первый аргумент всегда является указателем на объект определённого типа. Если возможно преобразование к общему «большему» типу, функция заменяет указатели на новые ссылки на преобразованные объекты и возвращает `0`. Если преобразование невозможно, функция возвращает `1`. Если установлено условие ошибки, она вернёт `-1`.765- Если установлен флаг [`Py_TPFLAGS_CHECKTYPES`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_CHECKTYPES), бинарные и тернарные функции должны проверять тип всех своих операндов и выполнять необходимые преобразования (по крайней мере один из операндов является экземпляром определённого типа). Это рекомендуемый способ; в Python 3 приведение полностью исчезнет.766767Если операция не определена для данных операндов, бинарные и тернарные функции должны вернуть `Py_NotImplemented`; если произошла другая ошибка, они должны вернуть `NULL` и установить исключение.768769# Структуры объектов отображения770771**`PyMappingMethods`**772773Эта структура хранит указатели на функции, которые объект использует для реализации протокола отображения. Она содержит три члена:774775**lenfunc `PyMappingMethods.mp_length`**776777Эта функция используется [`PyMapping_Length()`](https://python-all.ru/2.7/c-api/mapping.html#c.PyMapping_Length) и [`PyObject_Size()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Size) и имеет ту же сигнатуру. Этот слот может быть установлен в *NULL*, если у объекта нет определённой длины.778779**binaryfunc `PyMappingMethods.mp_subscript`**780781Эта функция используется [`PyObject_GetItem()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_GetItem) и имеет ту же сигнатуру. Этот слот должен быть заполнен, чтобы функция [`PyMapping_Check()`](https://python-all.ru/2.7/c-api/mapping.html#c.PyMapping_Check) возвращала `1`; в противном случае он может быть *NULL*.782783**objobjargproc `PyMappingMethods.mp_ass_subscript`**784785Эта функция используется [`PyObject_SetItem()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_SetItem) и [`PyObject_DelItem()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_DelItem). Она имеет ту же сигнатуру, что и [`PyObject_SetItem()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_SetItem), но *v* также может быть установлено в *NULL* для удаления элемента. Если этот слот равен *NULL*, объект не поддерживает присваивание и удаление элементов.786787# Структуры объектов последовательностей788789**`PySequenceMethods`**790791Эта структура содержит указатели на функции, которые объект использует для реализации протокола последовательности.792793**lenfunc `PySequenceMethods.sq_length`**794795Эта функция используется [`PySequence_Size()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_Size) и [`PyObject_Size()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_Size), и имеет ту же сигнатуру.796797**binaryfunc `PySequenceMethods.sq_concat`**798799Эта функция используется [`PySequence_Concat()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_Concat) и имеет ту же сигнатуру. Она также используется оператором `+` после попытки численного сложения через слот `nb_add`.800801**ssizeargfunc `PySequenceMethods.sq_repeat`**802803Эта функция используется [`PySequence_Repeat()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_Repeat) и имеет ту же сигнатуру. Она также используется оператором `*` после попытки числового умножения через `nb_multiply` слот.804805**ssizeargfunc `PySequenceMethods.sq_item`**806807Эта функция используется [`PySequence_GetItem()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_GetItem) и имеет ту же сигнатуру. Этот слот должен быть заполнен, чтобы функция [`PySequence_Check()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_Check) возвращала `1`; в противном случае он может быть *NULL*.808809Отрицательные индексы обрабатываются следующим образом: если слот `sq_length` заполнен, он вызывается, и длина последовательности используется для вычисления положительного индекса, который передаётся в `sq_item`. Если `sq_length` равно *NULL*, индекс передаётся функции как есть.810811**ssizeobjargproc `PySequenceMethods.sq_ass_item`**812813Эта функция используется [`PySequence_SetItem()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_SetItem) и имеет ту же сигнатуру. Этот слот может оставаться *NULL*, если объект не поддерживает присваивание и удаление элементов.814815**objobjproc `PySequenceMethods.sq_contains`**816817Эта функция может использоваться [`PySequence_Contains()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_Contains) и имеет ту же сигнатуру. Этот слот может оставаться *NULL*; в этом случае [`PySequence_Contains()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_Contains) просто проходит по последовательности, пока не найдёт совпадение.818819**binaryfunc `PySequenceMethods.sq_inplace_concat`**820821Эта функция используется [`PySequence_InPlaceConcat()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_InPlaceConcat) и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его.822823**ssizeargfunc `PySequenceMethods.sq_inplace_repeat`**824825Эта функция используется [`PySequence_InPlaceRepeat()`](https://python-all.ru/2.7/c-api/sequence.html#c.PySequence_InPlaceRepeat) и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его.826827# Структуры объектов буфера828829Буферный интерфейс предоставляет модель, в которой объект может раскрывать свои внутренние данные в виде набора блоков данных, где каждый блок задаётся парой указатель/длина. Эти блоки называются *сегментами* и предполагаются не смежными в памяти.830831Если объект не предоставляет буферный интерфейс, его член [`tp_as_buffer`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer) в структуре [`PyTypeObject`](https://python-all.ru/2.7/c-api/type.html#c.PyTypeObject) должен быть *NULL*. В противном случае [`tp_as_buffer`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer) будет указывать на структуру [`PyBufferProcs`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyBufferProcs).832833> **Примечание**834>835> Очень важно, чтобы ваша структура [`PyTypeObject`](https://python-all.ru/2.7/c-api/type.html#c.PyTypeObject) использовала [`Py_TPFLAGS_DEFAULT`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_DEFAULT) в качестве значения члена [`tp_flags`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_flags), а не `0`. Это сообщает среде выполнения Python, что ваша структура [`PyBufferProcs`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyBufferProcs) содержит слот `bf_getcharbuffer`. В старых версиях Python этого члена не было, поэтому новая версия интерпретатора Python, использующая старое расширение, должна уметь проверять его наличие перед использованием.836837**`PyBufferProcs`**838839Структура, используемая для хранения указателей на функции, определяющие реализацию протокола буфера.840841Первый слот – `bf_getreadbuffer`, типа [`readbufferproc`](https://python-all.ru/2.7/c-api/typeobj.html#c.readbufferproc). Если этот слот равен *NULL*, то объект не поддерживает чтение внутренних данных. Это бессмысленно, поэтому разработчики должны заполнять этот слот, но вызывающие стороны должны проверять, что слот содержит значение, отличное от *NULL*.842843Следующий слот – `bf_getwritebuffer`, с типом [`writebufferproc`](https://python-all.ru/2.7/c-api/typeobj.html#c.writebufferproc). Этот слот может быть *NULL*, если объект не разрешает запись в возвращаемые буферы.844845Третий слот – `bf_getsegcount`, с типом [`segcountproc`](https://python-all.ru/2.7/c-api/typeobj.html#c.segcountproc). Этот слот не должен быть *NULL* и используется для сообщения вызывающей стороне о количестве сегментов, которые содержит объект. Простые объекты, такие как [`PyString_Type`](https://python-all.ru/2.7/c-api/string.html#c.PyString_Type) и [`PyBuffer_Type`](https://python-all.ru/2.7/c-api/buffer.html#c.PyBuffer_Type), содержат один сегмент.846847Последний слот – `bf_getcharbuffer`, типа [`charbufferproc`](https://python-all.ru/2.7/c-api/typeobj.html#c.charbufferproc). Этот слот будет присутствовать, только если флаг [`Py_TPFLAGS_HAVE_GETCHARBUFFER`](https://python-all.ru/2.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GETCHARBUFFER) присутствует в поле [`tp_flags`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_flags) структуры [`PyTypeObject`](https://python-all.ru/2.7/c-api/type.html#c.PyTypeObject) объекта. Перед использованием этого слота вызывающая сторона должна проверить его наличие с помощью функции [`PyType_HasFeature()`](https://python-all.ru/2.7/c-api/type.html#c.PyType_HasFeature). Если флаг присутствует, `bf_getcharbuffer` может быть *NULL*, что означает, что содержимое объекта не может использоваться как *8-битные символы*. Слотовая функция также может вызвать ошибку, если содержимое объекта не удаётся интерпретировать как 8-битные символы. Например, если объект является массивом, настроенным на хранение чисел с плавающей точкой, может быть возбуждено исключение, если вызывающая сторона попытается использовать `bf_getcharbuffer` для получения последовательности 8-битных символов. Это понятие экспорта внутренних буферов как «текста» используется для различения объектов, имеющих двоичную природу, и объектов с символьным содержимым.848849> **Примечание**850>851> Текущая политика, по-видимому, утверждает, что эти символы могут быть многобайтовыми. Это означает, что размер буфера *N* не означает, что присутствует *N* символов.852853#### `Py_TPFLAGS_HAVE_GETCHARBUFFER`854855Бит флага, установленный в структуре типа, чтобы указать, что слот `bf_getcharbuffer` известен. Его установка не означает, что объект поддерживает буферный интерфейс или что слот `bf_getcharbuffer` не равен *NULL*.856857**Py\_ssize\_t `(*readbufferproc)`([PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) *\*self*, Py\_ssize\_t *segment*, void *\*\*ptrptr*)**858859Возвращает указатель на читаемый сегмент буфера в `*ptrptr`. Эта функция может вызывать исключение; в этом случае она должна вернуть `-1`. Указанный *сегмент* должен быть нулевым или положительным и строго меньше количества сегментов, возвращаемых функцией слота `bf_getsegcount`. В случае успеха возвращается длина сегмента, а `*ptrptr` устанавливается в указатель на эту память.860861**Py\_ssize\_t `(*writebufferproc)`([PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) *\*self*, Py\_ssize\_t *segment*, void *\*\*ptrptr*)**862863Возвращает указатель на буфер памяти для записи в `*ptrptr`, а длину этого сегмента – как возвращаемое значение функции. Буфер памяти должен соответствовать сегменту буфера *сегмент*. Должен вернуть `-1` и установить исключение при ошибке. [`TypeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.TypeError) должно быть вызвано, если объект поддерживает только буферы только для чтения, а [`SystemError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.SystemError) – когда *сегмент* указывает на несуществующий сегмент.864865**Py\_ssize\_t `(*segcountproc)`([PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) *\*self*, Py\_ssize\_t *\*lenp*)**866867Возвращает количество сегментов памяти, составляющих буфер. Если *lenp* не равно *NULL*, реализация должна вернуть сумму размеров (в байтах) всех сегментов в `*lenp`. Эта функция не может завершиться ошибкой.868869**Py\_ssize\_t `(*charbufferproc)`([PyObject](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) *\*self*, Py\_ssize\_t *segment*, char *\*\*ptrptr*)**870871Возвращает размер сегмента *сегмент*, на который указывает *ptrptr*. `*ptrptr` устанавливается на буфер памяти. В случае ошибки возвращает `-1`.872