typeobj.md
1> **Источник:** https://python-all.ru/3.0/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.0/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.0/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.0/c-api/structures.html#PyVarObject). Поле [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size) используется для динамических типов (создаваемых с помощью `type_new()`, обычно вызываемого из определения класса). Обратите внимание, что [`PyType_Type`](https://python-all.ru/3.0/c-api/type.html#PyType_Type) (метатип) инициализирует [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize), а это означает, что его экземпляры (т.е. объекты типов) *должны* иметь поле [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size).9495**\[\_ob\_next\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* [PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject).`_ob_next`**9697**[PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* [PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject).`_ob_prev`**9899These fields are only present when the macro `Py_TRACE_REFS` is defined. Their initialization to *NULL* is taken care of by the `PyObject_HEAD_INIT` macro. For statically allocated objects, these fields always remain *NULL*. For dynamically allocated objects, these two fields are used to link the object into a doubly-linked list of *all* live objects on the heap. This could be used for various debugging purposes; currently the only use is to print the objects that are still alive at the end of a run when the environment variable [**PYTHONDUMPREFS**](https://python-all.ru/3.0/using/cmdline.html#envvar-PYTHONDUMPREFS) is set.100101Эти поля не наследуются подтипами.102103**\[ob\_refcnt\]Py\_ssize\_t [PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject).`ob_refcnt`**104105Это счётчик ссылок объекта типа, инициализируемый значением `1` макросом `PyObject_HEAD_INIT`. Обратите внимание, что для статически размещённых объектов типа экземпляры типа (объекты, чьё поле [`ob_type`](https://python-all.ru/3.0/c-api/typeobj.html#ob_type) указывает обратно на тип) *не* считаются ссылками. Но для динамически размещённых объектов типа экземпляры *всё же* считаются ссылками.106107Это поле не наследуется подтипами.108109**\[ob\_type\][PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject)\* [PyObject](https://python-all.ru/3.0/c-api/structures.html#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.0/c-api/type.html#PyType_Ready) проверяет, не равен ли [`ob_type`](https://python-all.ru/3.0/c-api/typeobj.html#ob_type) значению *NULL*, и если это так, инициализирует его полем [`ob_type`](https://python-all.ru/3.0/c-api/typeobj.html#ob_type) базового класса. [`PyType_Ready`](https://python-all.ru/3.0/c-api/type.html#PyType_Ready) не будет изменять это поле, если оно не равно нулю.118119Это поле наследуется подтипами.120121**\[ob\_size\]Py\_ssize\_t [PyVarObject](https://python-all.ru/3.0/c-api/structures.html#PyVarObject).`ob_size`**122123Для статически выделенных объектов-типов это поле должно быть инициализировано нулём. Для динамически выделенных объектов-типов это поле имеет особый внутренний смысл.124125Это поле не наследуется подтипами.126127**\[tp\_name\]char\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_name`**128129Указатель на строку, завершающуюся NUL, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка и имя типа; для встроенных типов – только имя типа. Если модуль является подмодулем пакета, полное имя пакета входит в полное имя модуля. Например, тип с именем `T`, определённый в модуле `M` в подпакете `Q` пакета `P`, должен иметь инициализатор [`tp_name`](https://python-all.ru/3.0/c-api/typeobj.html#tp_name) `"P.Q.M.T"`.130131Для динамически выделенных объектов типов это должно быть просто имя типа, а имя модуля должно явно храниться в словаре типа как значение ключа `'__module__'`.132133Для статически размещённых объектов типов поле tp\_name должно содержать точку. Всё, что находится перед последней точкой, становится доступным как атрибут `__module__`, а всё, что после последней точки, – как атрибут `__name__`.134135Если точка отсутствует, всё поле [`tp_name`](https://python-all.ru/3.0/c-api/typeobj.html#tp_name) становится доступным как атрибут `__name__`, а атрибут `__module__` не определён (если только он не задан явно в словаре, как описано выше). Это означает, что ваш тип невозможно будет сериализовать с помощью pickle.136137Это поле не наследуется подтипами.138139**\[tp\_basicsize\]Py\_ssize\_t [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_basicsize`**140141**Py\_ssize\_t [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_itemsize`**142143Эти поля позволяют вычислить размер экземпляров типа в байтах.144145Существует два вида типов: типы с экземплярами фиксированной длины имеют нулевое поле [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize), а типы с экземплярами переменной длины – ненулевое поле [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize). Для типа с экземплярами фиксированной длины все экземпляры имеют одинаковый размер, задаваемый в [`tp_basicsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_basicsize).146147Для типа с экземплярами переменной длины экземпляры должны иметь поле [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size), а размер экземпляра равен [`tp_basicsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_basicsize) плюс N, умноженное на [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize), где N – «длина» объекта. Значение N обычно хранится в поле [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size) экземпляра. Бывают исключения: например, int использует отрицательное значение [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size) для обозначения отрицательного числа, и тогда N равно `abs(ob_size)`. Кроме того, наличие поля [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size) в структуре экземпляра не означает, что структура экземпляра имеет переменную длину (например, структура для типа list имеет экземпляры фиксированной длины, но эти экземпляры содержат осмысленное поле [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size)).148149Базовый размер включает поля экземпляра, объявленные макросом [`PyObject_HEAD`](https://python-all.ru/3.0/c-api/structures.html#PyObject_HEAD) или [`PyObject_VAR_HEAD`](https://python-all.ru/3.0/c-api/structures.html#PyObject_VAR_HEAD) (в зависимости от того, какой используется для объявления структуры экземпляра), и это, в свою очередь, включает поля [`_ob_prev`](https://python-all.ru/3.0/c-api/typeobj.html#_ob_prev) и [`_ob_next`](https://python-all.ru/3.0/c-api/typeobj.html#_ob_next), если они присутствуют. Это означает, что единственный правильный способ получить инициализатор для [`tp_basicsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_basicsize) – использовать оператор `sizeof` для структуры, используемой для объявления экземпляра. Базовый размер не включает размер заголовка GC.150151Эти поля наследуются подтипами отдельно. Если базовый тип имеет ненулевое [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize), то, как правило, небезопасно устанавливать [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize) в другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).152153Замечание о выравнивании: если элементы переменной длины требуют определённого выравнивания, это должно обеспечиваться значением [`tp_basicsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_basicsize). Пример: предположим, тип реализует массив из `double`. [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize) равно `sizeof(double)`. Ответственность программиста – сделать так, чтобы [`tp_basicsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_basicsize) было кратно `sizeof(double)` (предполагая, что это требование выравнивания для `double`).154155**\[tp\_dealloc\]destructor [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_dealloc`**156157Указатель на функцию-деструктор экземпляра. Эта функция должна быть определена, если только тип не гарантирует, что его экземпляры никогда не будут освобождены (как в случае с синглтонами `None` и `Ellipsis`).158159Функция-деструктор вызывается макросами [`Py_DECREF`](https://python-all.ru/3.0/c-api/refcounting.html#Py_DECREF) и [`Py_XDECREF`](https://python-all.ru/3.0/c-api/refcounting.html#Py_XDECREF), когда счётчик ссылок становится равным нулю. В этот момент экземпляр ещё существует, но на него нет ссылок. Функция-деструктор должна освободить все ссылки, которыми владеет экземпляр, освободить все буферы памяти, принадлежащие экземпляру (используя функцию освобождения, соответствующую функции выделения, которая использовалась для выделения буфера), и наконец (как последнее действие) вызвать функцию [`tp_free`](https://python-all.ru/3.0/c-api/typeobj.html#tp_free) типа. Если тип не может быть подтипизирован (не имеет установленного бита флага [`Py_TPFLAGS_BASETYPE`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_BASETYPE)), то допустимо вызывать деаллокатор объекта напрямую, а не через [`tp_free`](https://python-all.ru/3.0/c-api/typeobj.html#tp_free). Деаллокатор объекта должен быть тем же, который использовался для выделения экземпляра; обычно это [`PyObject_Del`](https://python-all.ru/3.0/c-api/allocation.html#PyObject_Del), если экземпляр был выделен с помощью [`PyObject_New`](https://python-all.ru/3.0/c-api/allocation.html#PyObject_New) или `PyObject_VarNew`, или [`PyObject_GC_Del`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_Del), если экземпляр был выделен с помощью [`PyObject_GC_New`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_New) или `PyObject_GC_VarNew`.160161Это поле наследуется подтипами.162163**\[tp\_print\]printfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_print`**164165Необязательный указатель на функцию печати экземпляра.166167Функция печати вызывается только тогда, когда экземпляр выводится в *настоящий* файл; при выводе в псевдо-файл (например, в экземпляр `StringIO`), для преобразования в строку вызывается функция [`tp_repr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_repr) или [`tp_str`](https://python-all.ru/3.0/c-api/typeobj.html#tp_str) экземпляра. Они также вызываются, когда поле [`tp_print`](https://python-all.ru/3.0/c-api/typeobj.html#tp_print) типа равно *NULL*. Тип ни в коем случае не должен реализовывать [`tp_print`](https://python-all.ru/3.0/c-api/typeobj.html#tp_print) так, чтобы его вывод отличался от вывода [`tp_repr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_repr) или [`tp_str`](https://python-all.ru/3.0/c-api/typeobj.html#tp_str).168169Функция печати вызывается с той же сигнатурой, что и [`PyObject_Print`](https://python-all.ru/3.0/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`](https://python-all.ru/3.0/c-api/typeobj.html#tp_str); когда бит флага `Py_PRINT_RAW` сброшен, экземпляр должен печататься так же, как его форматировала бы функция [`tp_repr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_repr). Функция должна возвращать `-1` и устанавливать условие исключения в случае возникновения ошибки во время сравнения.170171Возможно, поле [`tp_print`](https://python-all.ru/3.0/c-api/typeobj.html#tp_print) будет объявлено устаревшим. В любом случае рекомендуется не определять [`tp_print`](https://python-all.ru/3.0/c-api/typeobj.html#tp_print), а вместо этого полагаться на [`tp_repr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_repr) и [`tp_str`](https://python-all.ru/3.0/c-api/typeobj.html#tp_str) для вывода.172173Это поле наследуется подтипами.174175**\[tp\_getattr\]getattrfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_getattr`**176177Необязательный указатель на функцию получения строки атрибута.178179Это поле устарело. Если оно определено, оно должно указывать на функцию, которая ведёт себя так же, как функция [`tp_getattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattro), но принимает C-строку вместо объекта строки Python для указания имени атрибута. Сигнатура такая же, как у [`PyObject_GetAttrString`](https://python-all.ru/3.0/c-api/object.html#PyObject_GetAttrString).180181Это поле наследуется подтипами вместе с [`tp_getattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattro): подтип наследует и [`tp_getattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattr), и [`tp_getattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattr) и [`tp_getattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattro) подтипа оба равны *NULL*.182183**\[tp\_setattr\]setattrfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_setattr`**184185Необязательный указатель на функцию установки строкового атрибута.186187Это поле устарело. Если оно определено, оно должно указывать на функцию, которая ведёт себя так же, как функция [`tp_setattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattro), но принимает C-строку вместо объекта строки Python для указания имени атрибута. Сигнатура такая же, как у [`PyObject_SetAttrString`](https://python-all.ru/3.0/c-api/object.html#PyObject_SetAttrString).188189Это поле наследуется подтипами вместе с [`tp_setattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattro): подтип наследует как [`tp_setattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattr), так и [`tp_setattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattro) от своего базового типа, когда [`tp_setattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattr) и [`tp_setattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattro) подтипа равны *NULL*.190191**\[tp\_reserved\]void\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_reserved`**192193Зарезервированный слот, ранее известный как tp\_compare.194195**\[tp\_repr\]reprfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_repr`**196197Необязательный указатель на функцию, реализующую встроенную функцию [`repr()`](https://python-all.ru/3.0/library/functions.html#repr).198199Сигнатура такая же, как у [`PyObject_Repr`](https://python-all.ru/3.0/c-api/object.html#PyObject_Repr); она должна возвращать строку или объект Unicode. В идеале эта функция должна возвращать строку, которая, будучи переданной в [`eval()`](https://python-all.ru/3.0/library/functions.html#eval) при подходящем окружении, возвращает объект с тем же значением. Если это невозможно, она должна возвращать строку, начинающуюся с `'<'` и заканчивающуюся `'>'`, по которой можно определить как тип, так и значение объекта.200201Если это поле не задано, возвращается строка вида `<%s object at %p>`, где `%s` заменяется на имя типа, а `%p` – на адрес памяти объекта.202203Это поле наследуется подтипами.204205**\[tp\_as\_number\][PyNumberMethods](https://python-all.ru/3.0/c-api/typeobj.html#PyNumberMethods)\* `tp_as_number`**206207Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих числовой протокол. Эти поля описаны в [*Структуры числовых объектов*](https://python-all.ru/3.0/c-api/typeobj.html#number-structs).208209Поле [`tp_as_number`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_number) не наследуется, но содержащиеся в нём поля наследуются по отдельности.210211**\[tp\_as\_sequence\][PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods)\* `tp_as_sequence`**212213Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол последовательности. Эти поля описаны в [*Структуры объектов-последовательностей*](https://python-all.ru/3.0/c-api/typeobj.html#sequence-structs).214215Поле [`tp_as_sequence`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_sequence) не наследуется, но содержащиеся в нём поля наследуются по отдельности.216217**\[tp\_as\_mapping\][PyMappingMethods](https://python-all.ru/3.0/c-api/typeobj.html#PyMappingMethods)\* `tp_as_mapping`**218219Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол отображения. Эти поля описаны в [*Структуры объектов-отображений*](https://python-all.ru/3.0/c-api/typeobj.html#mapping-structs).220221Поле [`tp_as_mapping`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_mapping) не наследуется, но содержащиеся в нём поля наследуются по отдельности.222223**\[tp\_hash\]hashfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_hash`**224225Необязательный указатель на функцию, реализующую встроенную функцию [`hash()`](https://python-all.ru/3.0/library/functions.html#hash).226227Сигнатура такая же, как у [`PyObject_Hash`](https://python-all.ru/3.0/c-api/object.html#PyObject_Hash); она должна возвращать C long. Значение `-1` не должно возвращаться как обычное возвращаемое значение; при возникновении ошибки во время вычисления хеш-значения функция должна установить исключение и вернуть `-1`.228229Это поле может быть явно установлено в [`PyObject_HashNotImplemented`](https://python-all.ru/3.0/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.0/c-api/object.html#PyObject_HashNotImplemented).230231Если это поле не установлено, попытка получить хеш объекта вызывает [`TypeError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.TypeError).232233Это поле наследуется подтипами вместе с [`tp_richcompare`](https://python-all.ru/3.0/c-api/typeobj.html#tp_richcompare): подтип наследует как [`tp_richcompare`](https://python-all.ru/3.0/c-api/typeobj.html#tp_richcompare), так и [`tp_hash`](https://python-all.ru/3.0/c-api/typeobj.html#tp_hash), когда [`tp_richcompare`](https://python-all.ru/3.0/c-api/typeobj.html#tp_richcompare) и [`tp_hash`](https://python-all.ru/3.0/c-api/typeobj.html#tp_hash) подтипа равны *NULL*.234235**\[tp\_call\]ternaryfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_call`**236237Необязательный указатель на функцию, реализующую вызов объекта. Должен быть *NULL*, если объект не является вызываемым. Сигнатура такая же, как у [`PyObject_Call`](https://python-all.ru/3.0/c-api/object.html#PyObject_Call).238239Это поле наследуется подтипами.240241**\[tp\_str\]reprfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_str`**242243Необязательный указатель на функцию, реализующую встроенную операцию [`str()`](https://python-all.ru/3.0/library/functions.html#str). (Обратите внимание, что [`str`](https://python-all.ru/3.0/library/functions.html#str) теперь является типом, и [`str()`](https://python-all.ru/3.0/library/functions.html#str) вызывает конструктор этого типа. Этот конструктор вызывает [`PyObject_Str`](https://python-all.ru/3.0/c-api/object.html#PyObject_Str) для выполнения фактической работы, а [`PyObject_Str`](https://python-all.ru/3.0/c-api/object.html#PyObject_Str) вызовет этот обработчик.)244245Сигнатура такая же, как для [`PyObject_Str`](https://python-all.ru/3.0/c-api/object.html#PyObject_Str); она должна возвращать строку или объект Unicode. Эта функция должна возвращать «дружественное» строковое представление объекта, так как именно это представление будет использоваться, в числе прочего, функцией [`print()`](https://python-all.ru/3.0/library/functions.html#print).246247Когда это поле не задано, для возврата строкового представления вызывается [`PyObject_Repr`](https://python-all.ru/3.0/c-api/object.html#PyObject_Repr).248249Это поле наследуется подтипами.250251**\[tp\_getattro\]getattrofunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_getattro`**252253Необязательный указатель на функцию получения атрибута.254255Сигнатура такая же, как для [`PyObject_GetAttr`](https://python-all.ru/3.0/c-api/object.html#PyObject_GetAttr). Обычно удобно установить это поле в `PyObject_GenericGetAttr`, что реализует обычный способ поиска атрибутов объекта.256257Это поле наследуется подтипами вместе с [`tp_getattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattr): подтип наследует как [`tp_getattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattr), так и [`tp_getattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattr) и [`tp_getattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_getattro) подтипа равны *NULL*.258259**\[tp\_setattro\]setattrofunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_setattro`**260261Необязательный указатель на функцию установки атрибута.262263Сигнатура такая же, как для [`PyObject_SetAttr`](https://python-all.ru/3.0/c-api/object.html#PyObject_SetAttr). Обычно удобно установить это поле в `PyObject_GenericSetAttr`, что реализует обычный способ установки атрибутов объекта.264265Это поле наследуется подтипами вместе с [`tp_setattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattr): подтип наследует как [`tp_setattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattr), так и [`tp_setattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattro) от базового типа, когда собственные поля [`tp_setattr`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattr) и [`tp_setattro`](https://python-all.ru/3.0/c-api/typeobj.html#tp_setattro) подтипа оба равны *NULL*.266267**\[tp\_as\_buffer\][PyBufferProcs](https://python-all.ru/3.0/c-api/typeobj.html#PyBufferProcs)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_as_buffer`**268269Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих буферный интерфейс. Эти поля описаны в [*Buffer Object Structures*](https://python-all.ru/3.0/c-api/typeobj.html#buffer-structs).270271Поле [`tp_as_buffer`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_buffer) не наследуется, но содержащиеся в нём поля наследуются по отдельности.272273**\[tp\_flags\]long [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_flags`**274275Это поле представляет собой битовую маску различных флагов. Некоторые флаги указывают на варианты семантики в определённых ситуациях; другие используются для обозначения того, что определённые поля в объекте типа (или в структурах расширения, на которые ссылаются [`tp_as_number`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_number), [`tp_as_sequence`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_sequence), [`tp_as_mapping`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_mapping) и [`tp_as_buffer`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_buffer)), которые исторически не всегда присутствовали, являются допустимыми; если такой бит флага сброшен, то поля типа, которые он защищает, не должны быть доступны и должны считаться имеющими нулевое значение или *NULL*.276277Наследование этого поля сложное. Большинство битов флагов наследуются по отдельности, т.е. если у базового типа установлен бит флага, подтип наследует этот бит флага. Биты флагов, относящиеся к структурам расширения, строго наследуются, если наследуется сама структура расширения – значение бита флага базового типа копируется в подтип вместе с указателем на структуру расширения. Бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) наследуется вместе с полями [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) и [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear), т.е. если [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) сброшен в подтипе, а [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) и [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) в подтипе существуют и имеют *NULL*.278279В настоящее время определены следующие битовые маски; их можно объединять с помощью оператора `|`, чтобы сформировать значение поля [`tp_flags`](https://python-all.ru/3.0/c-api/typeobj.html#tp_flags). Макрос [`PyType_HasFeature`](https://python-all.ru/3.0/c-api/type.html#PyType_HasFeature) принимает тип и значение флагов, *tp* и *f*, и проверяет, является ли `tp->tp_flags & f` ненулевым.280281#### `[Py_TPFLAGS_HEAPTYPE]Py_TPFLAGS_HEAPTYPE`282283Этот бит устанавливается, когда сам объект типа выделяется в куче. В этом случае поле284285[`ob_type`](https://python-all.ru/3.0/c-api/typeobj.html#ob_type)286287его экземпляров считается ссылкой на тип, и объект типа увеличивает счётчик ссылок (INCREF) при создании нового экземпляра и уменьшает (DECREF) при уничтожении экземпляра (это не относится к экземплярам подтипов; только тип, на который ссылается ob\_type экземпляра, получает INCREF или DECREF).288289#### `[Py_TPFLAGS_BASETYPE]Py_TPFLAGS_BASETYPE`290291Этот бит устанавливается, когда тип может использоваться как базовый тип другого типа. Если этот бит сброшен, тип не может быть унаследован (аналогично «финальному» классу в Java).292293#### `[Py_TPFLAGS_READY]Py_TPFLAGS_READY`294295Этот бит устанавливается, когда объект типа был полностью инициализирован с помощью296297[`PyType_Ready`](https://python-all.ru/3.0/c-api/type.html#PyType_Ready)298299.300301#### `[Py_TPFLAGS_READYING]Py_TPFLAGS_READYING`302303Этот бит устанавливается, пока304305[`PyType_Ready`](https://python-all.ru/3.0/c-api/type.html#PyType_Ready)306307находится в процессе инициализации объекта типа.308309#### `[Py_TPFLAGS_HAVE_GC]Py_TPFLAGS_HAVE_GC`310311Этот бит устанавливается, когда объект поддерживает сборку мусора. Если этот бит установлен, экземпляры должны создаваться с помощью312313[`PyObject_GC_New`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_New)314315и уничтожаться с помощью316317[`PyObject_GC_Del`](https://python-all.ru/3.0/c-api/gcsupport.html#PyObject_GC_Del)318319. Дополнительная информация приведена в разделе320321[*Supporting Cyclic Garbage Collection*](https://python-all.ru/3.0/c-api/gcsupport.html#supporting-cycle-detection)322323. Этот бит также означает, что в объекте типа присутствуют связанные со сборкой мусора поля324325[`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse)326327и328329[`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear)330331.332333#### `[Py_TPFLAGS_DEFAULT]Py_TPFLAGS_DEFAULT`334335Это битовая маска всех битов, относящихся к существованию определённых полей в объекте типа и его структурах расширения. В настоящее время она включает следующие биты:336337`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`338339,340341`Py_TPFLAGS_HAVE_VERSION_TAG`342343.344345**\[tp\_doc\]char\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_doc`**346347Необязательный указатель на C-строку, завершающуюся NUL, содержащую строку документации для этого объекта типа. Он доступен как атрибут `__doc__` у типа и его экземпляров.348349Это поле *не* наследуется подтипами.350351**\[tp\_traverse\][traverseproc](https://python-all.ru/3.0/c-api/gcsupport.html#traverseproc) [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_traverse`**352353Необязательный указатель на функцию обхода для сборщика мусора. Используется только если установлен бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Дополнительную информацию о схеме сборки мусора в Python можно найти в разделе [*Supporting Cyclic Garbage Collection*](https://python-all.ru/3.0/c-api/gcsupport.html#supporting-cycle-detection).354355Указатель [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) используется сборщиком мусора для обнаружения циклических ссылок. Типичная реализация функции [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) просто вызывает [`Py_VISIT`](https://python-all.ru/3.0/c-api/gcsupport.html#Py_VISIT) для каждого из членов экземпляра, являющихся объектами Python. Например, это функция `local_traverse` из модуля расширения [`_thread`](https://python-all.ru/3.0/library/_thread.html#module-_thread):356357```c358static int359local_traverse(localobject *self, visitproc visit, void *arg)360{361 Py_VISIT(self->args);362 Py_VISIT(self->kw);363 Py_VISIT(self->dict);364 return 0;365}366```367368Обратите внимание, что [`Py_VISIT`](https://python-all.ru/3.0/c-api/gcsupport.html#Py_VISIT) вызывается только для тех членов, которые могут участвовать в циклических ссылках. Хотя также есть член `self->key`, он может быть только *NULL* или строкой Python и поэтому не может быть частью циклической ссылки.369370С другой стороны, даже если известно, что член никогда не может быть частью цикла, в качестве средства отладки может потребоваться посетить его всё равно, чтобы функция `get_referents()` модуля [`gc`](https://python-all.ru/3.0/library/gc.html#module-gc) включала его.371372Обратите внимание, что [`Py_VISIT`](https://python-all.ru/3.0/c-api/gcsupport.html#Py_VISIT) требует, чтобы параметры *visit* и *arg* функции `local_traverse` имели именно эти имена; не называйте их как попало.373374Это поле наследуется подтипами вместе с [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) и битом флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): бит флага, [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) и [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) наследуются от базового типа, если все они равны нулю в подтипе.375376**\[tp\_clear\][inquiry](https://python-all.ru/3.0/c-api/gcsupport.html#inquiry) [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_clear`**377378Необязательный указатель на функцию очистки для сборщика мусора. Используется только если установлен бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).379380Функция-член [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) используется для разрыва циклических ссылок в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности все функции [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) в системе должны вместе разрывать все циклические ссылки. Это тонкий момент, и если есть сомнения, стоит предоставить функцию [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear). Например, тип tuple не реализует функцию [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear), поскольку можно доказать, что никакая циклическая ссылка не может состоять только из кортежей. Поэтому функции [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) других типов должны быть достаточны для разрыва любой циклической ссылки, содержащей кортеж. Это не сразу очевидно, и редко есть веская причина избегать реализации [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear).381382Реализации [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) должны обнулять ссылки экземпляра на те его члены, которые могут быть объектами Python, и устанавливать указатели на эти члены в *NULL*, как в следующем примере:383384```c385static int386local_clear(localobject *self)387{388 Py_CLEAR(self->key);389 Py_CLEAR(self->args);390 Py_CLEAR(self->kw);391 Py_CLEAR(self->dict);392 return 0;393}394```395396Следует использовать макрос [`Py_CLEAR`](https://python-all.ru/3.0/c-api/refcounting.html#Py_CLEAR), потому что очистка ссылок – деликатная операция: счетчик ссылок на содержащийся объект не должен уменьшаться, пока указатель на этот объект не будет установлен в *NULL*. Это связано с тем, что уменьшение счетчика ссылок может привести к тому, что содержащийся объект станет мусором, что запустит цепочку действий по его освобождению, которая может включать вызов произвольного кода Python (из-за финализаторов или колбэков слабых ссылок, связанных с содержащимся объектом). Если такой код может снова обратиться к *self*, важно, чтобы указатель на содержащийся объект в этот момент был *NULL*, чтобы *self* знал, что содержащийся объект больше нельзя использовать. Макрос [`Py_CLEAR`](https://python-all.ru/3.0/c-api/refcounting.html#Py_CLEAR) выполняет эти операции в безопасном порядке.397398Поскольку цель функций [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) – разрывать циклические ссылки, нет необходимости очищать содержащиеся объекты, такие как строки или целые числа Python, которые не могут участвовать в циклических ссылках. С другой стороны, может быть удобно очищать все содержащиеся объекты Python и реализовать функцию [`tp_dealloc`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dealloc) типа так, чтобы она вызывала [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear).399400Дополнительную информацию о схеме сборки мусора Python можно найти в разделе [*Поддержка циклической сборки мусора*](https://python-all.ru/3.0/c-api/gcsupport.html#supporting-cycle-detection).401402Это поле наследуется подтипами вместе с [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) и битом флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): бит флага, [`tp_traverse`](https://python-all.ru/3.0/c-api/typeobj.html#tp_traverse) и [`tp_clear`](https://python-all.ru/3.0/c-api/typeobj.html#tp_clear) наследуются от базового типа, если все они равны нулю в подтипе.403404**\[tp\_richcompare\]richcmpfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_richcompare`**405406Необязательный указатель на функцию сравнения с сигнатурой: `PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)`.407408Функция должна возвращать результат сравнения (обычно `Py_True` или `Py_False`). Если сравнение не определено, она должна вернуть `Py_NotImplemented`; если произошла другая ошибка – вернуть `NULL` и установить условие исключения.409410> **Примечание**411>412> Если требуется реализовать тип, для которого имеет смысл только ограниченный набор сравнений (например, `==` и `!=`, но не `<` и подобные), следует напрямую возбуждать [`TypeError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.TypeError) в функции расширенного сравнения.413414Это поле наследуется подтипами вместе с [`tp_hash`](https://python-all.ru/3.0/c-api/typeobj.html#tp_hash): подтип наследует [`tp_richcompare`](https://python-all.ru/3.0/c-api/typeobj.html#tp_richcompare) и [`tp_hash`](https://python-all.ru/3.0/c-api/typeobj.html#tp_hash), когда оба поля [`tp_richcompare`](https://python-all.ru/3.0/c-api/typeobj.html#tp_richcompare) и [`tp_hash`](https://python-all.ru/3.0/c-api/typeobj.html#tp_hash) подтипа равны *NULL*.415416Следующие константы определены для использования в качестве третьего аргумента для [`tp_richcompare`](https://python-all.ru/3.0/c-api/typeobj.html#tp_richcompare) и для [`PyObject_RichCompare`](https://python-all.ru/3.0/c-api/object.html#PyObject_RichCompare):417418| Константа | Сравнение |419| --- | --- |420| `Py_LT` | `<` |421| `Py_LE` | `<=` |422| `Py_EQ` | `==` |423| `Py_NE` | `!=` |424| `Py_GT` | `>` |425| `Py_GE` | `>=` |426427**\[tp\_weaklistoffset\]long [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_weaklistoffset`**428429Если экземпляры этого типа поддерживают слабые ссылки, это поле больше нуля и содержит смещение в структуре экземпляра до головы списка слабых ссылок (без учёта заголовка GC, если он присутствует); это смещение используется функциями `PyObject_ClearWeakRefs` и `PyWeakref_*`. Структура экземпляра должна содержать поле типа [`PyObject*`](https://python-all.ru/3.0/c-api/structures.html#PyObject), которое инициализируется значением *NULL*.430431Не путайте это поле с [`tp_weaklist`](https://python-all.ru/3.0/c-api/typeobj.html#tp_weaklist); это голова списка для слабых ссылок на сам объект типа.432433Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что подтип использует другую голову списка слабых ссылок, чем базовый тип. Поскольку голова списка всегда находится через [`tp_weaklistoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_weaklistoffset), это не должно быть проблемой.434435Если тип, определённый с помощью инструкции class, не содержит объявления `__slots__`, и ни один из его базовых типов не поддерживает слабые ссылки, то тип делается поддерживающим слабые ссылки путём добавления в разметку экземпляра заголовочного слота списка слабых ссылок и установки [`tp_weaklistoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_weaklistoffset) в смещение этого слота.436437Когда объявление `__slots__` типа содержит слот с именем `__weakref__`, этот слот становится головой списка слабых ссылок для экземпляров типа, а его смещение сохраняется в поле типа [`tp_weaklistoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_weaklistoffset).438439Если объявление `__slots__` типа не содержит слота с именем `__weakref__`, тип наследует своё значение [`tp_weaklistoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_weaklistoffset) от базового типа.440441**\[tp\_iter\]getiterfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_iter`**442443Необязательный указатель на функцию, возвращающую итератор для объекта. Его наличие обычно указывает на то, что экземпляры этого типа являются итерируемыми (хотя последовательности могут быть итерируемыми и без этой функции).444445Сигнатура этой функции совпадает с [`PyObject_GetIter`](https://python-all.ru/3.0/c-api/object.html#PyObject_GetIter).446447Это поле наследуется подтипами.448449**\[tp\_iternext\]iternextfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_iternext`**450451Необязательный указатель на функцию, возвращающую следующий элемент итератора. Когда итератор исчерпан, она должна вернуть *NULL*; исключение [`StopIteration`](https://python-all.ru/3.0/library/exceptions.html#exceptions.StopIteration) может быть установлено, а может и нет. При возникновении другой ошибки она также должна вернуть *NULL*. Наличие этой функции указывает, что экземпляры данного типа являются итераторами.452453Типы-итераторы также должны определять функцию [`tp_iter`](https://python-all.ru/3.0/c-api/typeobj.html#tp_iter), и эта функция должна возвращать сам экземпляр итератора (не новый экземпляр итератора).454455Сигнатура этой функции совпадает с [`PyIter_Next`](https://python-all.ru/3.0/c-api/iter.html#PyIter_Next).456457Это поле наследуется подтипами.458459**\[tp\_methods\]struct [PyMethodDef](https://python-all.ru/3.0/c-api/structures.html#PyMethodDef)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_methods`**460461Необязательный указатель на статический массив структур [`PyMethodDef`](https://python-all.ru/3.0/c-api/structures.html#PyMethodDef), завершающийся *NULL*, объявляющий обычные методы этого типа.462463Для каждой записи массива в словарь типа (см. [`tp_dict`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dict) ниже) добавляется запись, содержащая дескриптор метода.464465Это поле не наследуется подтипами (методы наследуются через другой механизм).466467**\[tp\_members\]struct [PyMemberDef](https://python-all.ru/3.0/c-api/structures.html#PyMemberDef)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_members`**468469Необязательный указатель на статический массив структур [`PyMemberDef`](https://python-all.ru/3.0/c-api/structures.html#PyMemberDef), завершающийся *NULL*, объявляющий обычные элементы данных (поля или слоты) экземпляров этого типа.470471Для каждой записи массива в словарь типа (см. [`tp_dict`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dict) ниже) добавляется запись, содержащая дескриптор элемента.472473Это поле не наследуется подтипами (члены наследуются через другой механизм).474475**\[tp\_getset\]struct PyGetSetDef\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_getset`**476477Необязательный указатель на статический массив структур `PyGetSetDef`, завершающийся *NULL*, объявляющий вычисляемые атрибуты экземпляров этого типа.478479Для каждой записи массива в словарь типа (см. [`tp_dict`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dict) ниже) добавляется запись, содержащая дескриптор getset.480481Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).482483Документация для PyGetSetDef (XXX должна быть в другом месте):484485```c486typedef PyObject *(*getter)(PyObject *, void *);487typedef int (*setter)(PyObject *, PyObject *, void *);488489typedef struct PyGetSetDef {490 char *name; /* имя атрибута */491 getter get; /* C-функция для получения атрибута */492 setter set; /* C-функция для установки атрибута */493 char *doc; /* необязательная строка документации */494 void *closure; /* необязательные дополнительные данные для геттера и сеттера */495} PyGetSetDef;496```497498**\[tp\_base\][PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_base`**499500Необязательный указатель на базовый тип, от которого наследуются свойства типа. На этом уровне поддерживается только одиночное наследование; множественное наследование требует динамического создания объекта типа вызовом метатипа.501502Это поле не наследуется подтипами (очевидно), но по умолчанию оно равно `&PyBaseObject_Type` (которое программистам Python известно как тип [`object`](https://python-all.ru/3.0/library/functions.html#object)).503504**\[tp\_dict\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_dict`**505506Словарь типа сохраняется здесь функцией [`PyType_Ready`](https://python-all.ru/3.0/c-api/type.html#PyType_Ready).507508Обычно это поле следует инициализировать значением *NULL* перед вызовом PyType\_Ready; также его можно инициализировать словарём, содержащим начальные атрибуты типа. После того как [`PyType_Ready`](https://python-all.ru/3.0/c-api/type.html#PyType_Ready) инициализирует тип, в этот словарь можно добавлять дополнительные атрибуты типа, только если они не соответствуют перегруженным операциям (например, [`__add__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__add__)).509510Это поле не наследуется подтипами (хотя определённые здесь атрибуты наследуются через другой механизм).511512**\[tp\_descr\_get\]descrgetfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_descr_get`**513514Необязательный указатель на функцию «descriptor get».515516Сигнатура функции:517518```c519PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);520```521522XXX объяснить.523524Это поле наследуется подтипами.525526**\[tp\_descr\_set\]descrsetfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_descr_set`**527528Необязательный указатель на функцию «установки дескриптора».529530Сигнатура функции:531532```c533int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);534```535536Это поле наследуется подтипами.537538XXX объяснить.539540**\[tp\_dictoffset\]long [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_dictoffset`**541542Если экземпляры этого типа имеют словарь, содержащий переменные экземпляра, это поле не равно нулю и содержит смещение в экземплярах типа до словаря переменных экземпляра; это смещение используется функцией `PyObject_GenericGetAttr`.543544Не путайте это поле с [`tp_dict`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dict); это словарь для атрибутов самого объекта типа.545546Если значение этого поля больше нуля, оно задаёт смещение от начала структуры экземпляра. Если значение меньше нуля, оно задаёт смещение от *конца* структуры экземпляра. Отрицательное смещение использовать дороже, и его следует применять только если структура экземпляра содержит часть переменной длины. Это используется, например, для добавления словаря переменных экземпляра к подтипам [`str`](https://python-all.ru/3.0/library/functions.html#str) или [`tuple`](https://python-all.ru/3.0/library/functions.html#tuple). Обратите внимание, что поле [`tp_basicsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_basicsize) должно учитывать словарь, добавленный в конец, даже если сам словарь не входит в базовую компоновку объекта. В системе с размером указателя 4 байта [`tp_dictoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dictoffset) должно быть установлено в `-4`, чтобы указать, что словарь находится в самом конце структуры.547548Реальное смещение словаря в экземпляре можно вычислить из отрицательного [`tp_dictoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dictoffset) следующим образом:549550```c551dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset552if dictoffset is not aligned on sizeof(void*):553 round up to sizeof(void*)554```555556где [`tp_basicsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_basicsize), [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize) и [`tp_dictoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dictoffset) берутся из объекта типа, а [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size) – из экземпляра. Берётся абсолютное значение, потому что целые числа (int) используют знак [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size) для хранения знака числа. (Никогда не нужно выполнять этот расчёт самостоятельно; за вас это делает `_PyObject_GetDictPtr`.)557558Это поле наследуется подтипами, но обратитесь к списку правил ниже. Подтип может переопределить это смещение; это означает, что экземпляры подтипа хранят словарь по другому смещению, нежели базовый тип. Поскольку словарь всегда находится через [`tp_dictoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dictoffset), это не должно вызывать проблем.559560Когда тип, определённый с помощью оператора class, не имеет объявления `__slots__`, и ни один из его базовых типов не имеет словаря переменных экземпляра, в размещение экземпляра добавляется слот для словаря, а [`tp_dictoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dictoffset) устанавливается в смещение этого слота.561562Если тип, определённый с помощью оператора class, содержит объявление `__slots__`, такой тип наследует свой [`tp_dictoffset`](https://python-all.ru/3.0/c-api/typeobj.html#tp_dictoffset) от базового типа.563564(Добавление слота с именем `__dict__` в объявление `__slots__` не дает ожидаемого эффекта, это только вызывает путаницу. Однако, возможно, эту возможность стоит добавить по аналогии с `__weakref__`.)565566**\[tp\_init\]initproc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_init`**567568Необязательный указатель на функцию инициализации экземпляра.569570Эта функция соответствует методу классов [`__init__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__init__). Как и для [`__init__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__init__), можно создать экземпляр, не вызывая [`__init__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__init__), а также можно переинициализировать экземпляр, повторно вызвав его метод [`__init__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__init__).571572Сигнатура функции:573574```c575int tp_init(PyObject *self, PyObject *args, PyObject *kwds)576```577578Аргумент self – это инициализируемый экземпляр; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова [`__init__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__init__).579580Функция [`tp_init`](https://python-all.ru/3.0/c-api/typeobj.html#tp_init), если она не *NULL*, вызывается при обычном создании экземпляра вызовом его типа, после того как функция [`tp_new`](https://python-all.ru/3.0/c-api/typeobj.html#tp_new) этого типа вернёт экземпляр данного типа. Если функция [`tp_new`](https://python-all.ru/3.0/c-api/typeobj.html#tp_new) возвращает экземпляр некоторого другого типа, не являющегося подтипом исходного, то функция [`tp_init`](https://python-all.ru/3.0/c-api/typeobj.html#tp_init) не вызывается; если же [`tp_new`](https://python-all.ru/3.0/c-api/typeobj.html#tp_new) возвращает экземпляр подтипа исходного типа, то вызывается [`tp_init`](https://python-all.ru/3.0/c-api/typeobj.html#tp_init) этого подтипа.581582Это поле наследуется подтипами.583584**\[tp\_alloc\]allocfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_alloc`**585586Необязательный указатель на функцию выделения экземпляра.587588Сигнатура функции:589590```c591PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)592```593594Назначение этой функции – разделить выделение памяти и её инициализацию. Она должна возвращать указатель на блок памяти достаточной длины для экземпляра, с подходящим выравниванием, обнулённый, но с [`ob_refcnt`](https://python-all.ru/3.0/c-api/typeobj.html#ob_refcnt), установленным в `1`, и [`ob_type`](https://python-all.ru/3.0/c-api/typeobj.html#ob_type), установленным в аргумент type. Если [`tp_itemsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_itemsize) типа не равен нулю, поле [`ob_size`](https://python-all.ru/3.0/c-api/typeobj.html#ob_size) объекта должно быть инициализировано значением *nitems*, а длина выделенного блока памяти должна быть `tp_basicsize + nitems*tp_itemsize`, округлённая вверх до кратного `sizeof(void*)`; в противном случае *nitems* не используется, и длина блока должна быть [`tp_basicsize`](https://python-all.ru/3.0/c-api/typeobj.html#tp_basicsize).595596Не используйте эту функцию для какой-либо другой инициализации экземпляра, даже для выделения дополнительной памяти; это должно делаться с помощью [`tp_new`](https://python-all.ru/3.0/c-api/typeobj.html#tp_new).597598Это поле наследуется статическими подтипами, но не динамическими (подтипами, созданными с помощью оператора class); в последних это поле всегда устанавливается в [`PyType_GenericAlloc`](https://python-all.ru/3.0/c-api/type.html#PyType_GenericAlloc), чтобы обеспечить стандартную стратегию выделения памяти в куче. Это же значение рекомендуется и для статически определённых типов.599600**\[tp\_new\]newfunc [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_new`**601602Необязательный указатель на функцию создания экземпляра.603604Если для данного типа эта функция равна *NULL*, то этот тип нельзя вызвать для создания новых экземпляров; предполагается, что существует другой способ создания экземпляров, например, фабричная функция.605606Сигнатура функции:607608```c609PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)610```611612Аргумент subtype – это тип создаваемого объекта; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова типа. Обратите внимание, что subtype не обязан совпадать с типом, чья функция [`tp_new`](https://python-all.ru/3.0/c-api/typeobj.html#tp_new) вызывается; это может быть подтип этого типа (но не какой-то другой, не связанный тип).613614Функция [`tp_new`](https://python-all.ru/3.0/c-api/typeobj.html#tp_new) должна вызывать `subtype->tp_alloc(subtype, nitems)` для выделения памяти под объект, а затем выполнять лишь ту дополнительную инициализацию, которая абсолютно необходима. Инициализация, которую можно безопасно пропустить или повторить, должна быть помещена в обработчик [`tp_init`](https://python-all.ru/3.0/c-api/typeobj.html#tp_init). Хорошее эмпирическое правило: для неизменяемых типов вся инициализация должна происходить в [`tp_new`](https://python-all.ru/3.0/c-api/typeobj.html#tp_new), а для изменяемых типов большую часть инициализации следует откладывать до [`tp_init`](https://python-all.ru/3.0/c-api/typeobj.html#tp_init).615616Это поле наследуется подтипами, за исключением статических типов, у которых [`tp_base`](https://python-all.ru/3.0/c-api/typeobj.html#tp_base) равно *NULL* или `&PyBaseObject_Type`.617618**\[tp\_free\]destructor [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_free`**619620Необязательный указатель на функцию освобождения экземпляра. Её сигнатура – `freefunc`:621622```c623void tp_free(void *)624```625626Инициализатор, совместимый с этой сигнатурой, – это `PyObject_Free`.627628Это поле наследуется статическими подтипами, но не динамическими (подтипами, созданными с помощью оператора class); в последних это поле устанавливается в деаллокатор, подходящий для [`PyType_GenericAlloc`](https://python-all.ru/3.0/c-api/type.html#PyType_GenericAlloc) и значения бита флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).629630**\[tp\_is\_gc\][inquiry](https://python-all.ru/3.0/c-api/gcsupport.html#inquiry) [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_is_gc`**631632Необязательный указатель на функцию, вызываемую сборщиком мусора.633634Сборщику мусора необходимо знать, подлежит ли конкретный объект сборке или нет. Обычно достаточно посмотреть на поле [`tp_flags`](https://python-all.ru/3.0/c-api/typeobj.html#tp_flags) типа объекта и проверить флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.0/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Но у некоторых типов имеется смесь статически и динамически выделенных экземпляров, и статически выделенные экземпляры не подлежат сборке. Таким типам следует определить эту функцию; она должна возвращать `1` для подлежащего сборке экземпляра и `0` – для неподлежащего. Сигнатура:635636```c637int tp_is_gc(PyObject *self)638```639640(Единственный пример этого – сами типы. Метатип [`PyType_Type`](https://python-all.ru/3.0/c-api/type.html#PyType_Type) определяет эту функцию, чтобы различать статически и динамически выделенные типы.)641642Это поле наследуется подтипами.643644**\[tp\_bases\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_bases`**645646Кортеж базовых типов.647648Это устанавливается для типов, созданных с помощью оператора class. Для статически определённых типов оно должно быть равно *NULL*.649650Это поле не наследуется.651652**\[tp\_mro\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_mro`**653654Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая [`object`](https://python-all.ru/3.0/library/functions.html#object), в порядке разрешения методов (MRO).655656Это поле не наследуется; оно вычисляется заново функцией [`PyType_Ready`](https://python-all.ru/3.0/c-api/type.html#PyType_Ready).657658**\[tp\_cache\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_cache`**659660Не используется. Не наследуется. Только для внутреннего использования.661662**\[tp\_subclasses\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_subclasses`**663664Список слабых ссылок на подклассы. Не наследуется. Только для внутреннего использования.665666**\[tp\_weaklist\][PyObject](https://python-all.ru/3.0/c-api/structures.html#PyObject)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_weaklist`**667668Голова списка слабых ссылок для слабых ссылок на этот объект типа. Не наследуется. Только для внутреннего использования.669670Оставшиеся поля определяются только если определён макрос тестирования функциональности `COUNT_ALLOCS`, и предназначены только для внутреннего использования. Они dокументированы здесь для полноты. Ни одно из этих полей не наследуется подтипами.671672**\[tp\_allocs\]Py\_ssize\_t [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_allocs`**673674Количество выделений памяти.675676**\[tp\_frees\]Py\_ssize\_t [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_frees`**677678Количество освобождений.679680**\[tp\_maxalloc\]Py\_ssize\_t [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_maxalloc`**681682Максимальное количество одновременно выделенных объектов.683684**\[tp\_next\][PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject)\* [PyTypeObject](https://python-all.ru/3.0/c-api/type.html#PyTypeObject).`tp_next`**685686Указатель на следующий объект типа с ненулевым полем687688[`tp_allocs`](https://python-all.ru/3.0/c-api/typeobj.html#tp_allocs)689690.691692Также следует отметить, что в Python со сборкой мусора tp\_dealloc может вызываться из любого потока Python, а не только из того, который создал объект (если объект становится частью цикла подсчёта ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Это не проблема для вызовов Python API, поскольку поток, в котором вызывается tp\_dealloc, будет владеть глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект, в свою очередь, уничтожает объекты из какой-либо другой библиотеки C или C++, следует соблюдать осторожность, чтобы убедиться, что уничтожение этих объектов в потоке, вызвавшем tp\_dealloc, не нарушит никаких предположений библиотеки.693694# Структуры числовых объектов695696**\[PyNumberMethods\]`PyNumberMethods`**697698Эта структура содержит указатели на функции, которые объект использует для реализации числового протокола. Каждая функция используется одноимённой функцией, описанной в разделе [*Числовой протокол*](https://python-all.ru/3.0/c-api/number.html#number).699700Вот определение структуры:701702```c703typedef struct {704 binaryfunc nb_add;705 binaryfunc nb_subtract;706 binaryfunc nb_multiply;707 binaryfunc nb_remainder;708 binaryfunc nb_divmod;709 ternaryfunc nb_power;710 unaryfunc nb_negative;711 unaryfunc nb_positive;712 unaryfunc nb_absolute;713 inquiry nb_bool;714 unaryfunc nb_invert;715 binaryfunc nb_lshift;716 binaryfunc nb_rshift;717 binaryfunc nb_and;718 binaryfunc nb_xor;719 binaryfunc nb_or;720 unaryfunc nb_int;721 void *nb_reserved;722 unaryfunc nb_float;723724 binaryfunc nb_inplace_add;725 binaryfunc nb_inplace_subtract;726 binaryfunc nb_inplace_multiply;727 binaryfunc nb_inplace_remainder;728 ternaryfunc nb_inplace_power;729 binaryfunc nb_inplace_lshift;730 binaryfunc nb_inplace_rshift;731 binaryfunc nb_inplace_and;732 binaryfunc nb_inplace_xor;733 binaryfunc nb_inplace_or;734735 binaryfunc nb_floor_divide;736 binaryfunc nb_true_divide;737 binaryfunc nb_inplace_floor_divide;738 binaryfunc nb_inplace_true_divide;739740 unaryfunc nb_index;741} PyNumberMethods;742```743744> **Примечание**745>746> Бинарные и тернарные функции должны проверять тип всех своих операндов и выполнять необходимые преобразования (хотя бы один из операндов является экземпляром определённого типа). Если операция не определена для данных операндов, бинарные и тернарные функции должны вернуть `Py_NotImplemented`; если произошла другая ошибка, они должны вернуть `NULL` и установить исключение.747748> **Примечание**749>750> Поле `nb_reserved` всегда должно быть `NULL`. Ранее оно называлось `nb_long` и было переименовано в Python 3.0.1.751752# Структуры объектов отображения753754**\[PyMappingMethods\]`PyMappingMethods`**755756Эта структура хранит указатели на функции, которые объект использует для реализации протокола отображения. Она содержит три члена:757758**\[mp\_length\]lenfunc [PyMappingMethods](https://python-all.ru/3.0/c-api/typeobj.html#PyMappingMethods).`mp_length`**759760Эта функция используется761762[`PyMapping_Length`](https://python-all.ru/3.0/c-api/mapping.html#PyMapping_Length)763764и765766[`PyObject_Size`](https://python-all.ru/3.0/c-api/object.html#PyObject_Size)767768, и имеет ту же сигнатуру. Этот слот может быть установлен в769770*NULL*771772, если у объекта нет определённой длины.773774**\[mp\_subscript\]binaryfunc [PyMappingMethods](https://python-all.ru/3.0/c-api/typeobj.html#PyMappingMethods).`mp_subscript`**775776Эта функция используется777778[`PyObject_GetItem`](https://python-all.ru/3.0/c-api/object.html#PyObject_GetItem)779780и имеет ту же сигнатуру. Этот слот должен быть заполнен, чтобы функция781782[`PyMapping_Check`](https://python-all.ru/3.0/c-api/mapping.html#PyMapping_Check)783784возвращала785786`1`787788; в противном случае он может быть789790*NULL*791792.793794**\[mp\_ass\_subscript\]objobjargproc [PyMappingMethods](https://python-all.ru/3.0/c-api/typeobj.html#PyMappingMethods).`mp_ass_subscript`**795796Эта функция используется797798[`PyObject_SetItem`](https://python-all.ru/3.0/c-api/object.html#PyObject_SetItem)799800и имеет ту же сигнатуру. Если этот слот равен801802*NULL*803804, объект не поддерживает присваивание по индексу.805806# Структуры объектов последовательностей807808**\[PySequenceMethods\]`PySequenceMethods`**809810Эта структура содержит указатели на функции, которые объект использует для реализации протокола последовательности.811812**\[sq\_length\]lenfunc [PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods).`sq_length`**813814Эта функция используется815816[`PySequence_Size`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_Size)817818и819820[`PyObject_Size`](https://python-all.ru/3.0/c-api/object.html#PyObject_Size)821822, и имеет ту же сигнатуру.823824**\[sq\_concat\]binaryfunc [PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods).`sq_concat`**825826Эта функция используется827828[`PySequence_Concat`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_Concat)829830и имеет ту же сигнатуру. Она также используется оператором831832`+`833834, после попытки числового сложения через слот835836`tp_as_number.nb_add`837838.839840**\[sq\_repeat\]ssizeargfunc [PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods).`sq_repeat`**841842Эта функция используется843844[`PySequence_Repeat`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_Repeat)845846и имеет ту же сигнатуру. Она также используется оператором847848`*`849850, после попытки числового умножения через слот851852`tp_as_number.nb_mul`853854.855856**\[sq\_item\]ssizeargfunc [PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods).`sq_item`**857858Эта функция используется [`PySequence_GetItem`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_GetItem) и имеет ту же сигнатуру. Этот слот должен быть заполнен, чтобы функция [`PySequence_Check`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_Check) возвращала `1`; в противном случае он может быть *NULL*.859860Отрицательные индексы обрабатываются следующим образом: если слот [`sq_length`](https://python-all.ru/3.0/c-api/typeobj.html#sq_length) заполнен, он вызывается, и длина последовательности используется для вычисления положительного индекса, который передаётся в [`sq_item`](https://python-all.ru/3.0/c-api/typeobj.html#sq_item). Если [`sq_length`](https://python-all.ru/3.0/c-api/typeobj.html#sq_length) равен *NULL*, индекс передаётся функции как есть.861862**\[sq\_ass\_item\]ssizeobjargproc [PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods).`sq_ass_item`**863864Эта функция используется865866[`PySequence_SetItem`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_SetItem)867868и имеет ту же сигнатуру. Этот слот может оставаться равным869870*NULL*871872, если объект не поддерживает присваивание по индексу.873874**\[sq\_contains\]objobjproc [PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods).`sq_contains`**875876Эта функция может использоваться877878[`PySequence_Contains`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_Contains)879880и имеет ту же сигнатуру. Этот слот может оставаться равным881882*NULL*883884; в этом случае885886[`PySequence_Contains`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_Contains)887888просто проходит по последовательности, пока не найдёт совпадение.889890**\[sq\_inplace\_concat\]binaryfunc [PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods).`sq_inplace_concat`**891892Эта функция используется893894[`PySequence_InPlaceConcat`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_InPlaceConcat)895896и имеет ту же сигнатуру. Она должна изменять свой первый операнд и возвращать его.897898**\[sq\_inplace\_repeat\]ssizeargfunc [PySequenceMethods](https://python-all.ru/3.0/c-api/typeobj.html#PySequenceMethods).`sq_inplace_repeat`**899900Эта функция используется901902[`PySequence_InPlaceRepeat`](https://python-all.ru/3.0/c-api/sequence.html#PySequence_InPlaceRepeat)903904и имеет ту же сигнатуру. Она должна изменять свой первый операнд и возвращать его.905906# Структуры объектов буфера907908Интерфейс буфера предоставляет модель, в которой объект может раскрывать свои внутренние данные.909910Если объект не предоставляет буферный интерфейс, то его поле [`tp_as_buffer`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_buffer) в структуре [`PyTypeObject`](https://python-all.ru/3.0/c-api/type.html#PyTypeObject) должно быть *NULL*. В противном случае [`tp_as_buffer`](https://python-all.ru/3.0/c-api/typeobj.html#tp_as_buffer) будет указывать на структуру [`PyBufferProcs`](https://python-all.ru/3.0/c-api/typeobj.html#PyBufferProcs).911912**\[PyBufferProcs\]`PyBufferProcs`**913914Структура, используемая для хранения указателей на функции, определяющие реализацию протокола буфера.915916**\[bf\_getbuffer\]getbufferproc `bf_getbuffer`**917918Этот метод должен заполнить структуру919920[`Py_buffer`](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer)921922необходимыми данными для экспорта типа. Сигнатура923924`getbufferproc`925926имеет вид927928`int (PyObject *obj, PyObject *view, int flags)`929930.931932*obj*933934– экспортируемый объект,935936*view*937938– заполняемая структура939940[`Py_buffer`](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer)941942, а943944*flags*945946задаёт условия, на которых вызывающий хочет получить память. (Все флаги перечислены в947948[`PyObject_GetBuffer`](https://python-all.ru/3.0/c-api/buffer.html#PyObject_GetBuffer)949950.)951952[`bf_getbuffer`](https://python-all.ru/3.0/c-api/typeobj.html#bf_getbuffer)953954отвечает за заполнение955956*view*957958соответствующей информацией. (В простых случаях можно воспользоваться959960`PyBuffer_FillView`961962.) Смотрите документацию963964[`Py_buffer`](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer)965966о том, что нужно заполнить.967968**\[bf\_releasebuffer\]releasebufferproc `bf_releasebuffer`**969970Эта функция должна освобождать ресурсы буфера. Сигнатура `releasebufferproc`: `void (PyObject *obj, Py_buffer *view)`. Если функция [`bf_releasebuffer`](https://python-all.ru/3.0/c-api/typeobj.html#bf_releasebuffer) не предоставлена (т.е. равна *NULL*), то её никогда не нужно вызывать.971972Экспортёр буферного интерфейса должен гарантировать, что любая память, на которую указывает структура [`Py_buffer`](https://python-all.ru/3.0/c-api/buffer.html#Py_buffer), остаётся действительной до вызова releasebuffer. Экспортёрам потребуется определить функцию [`bf_releasebuffer`](https://python-all.ru/3.0/c-api/typeobj.html#bf_releasebuffer), если они могут перераспределять свою память, шаги, форму, подофсеты или переменные формата, которыми они могут обмениваться через struct bufferinfo.973974Смотрите [`PyBuffer_Release`](https://python-all.ru/3.0/c-api/buffer.html#PyBuffer_Release).975