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

typeobj.md

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

1> **Источник:** https://python-all.ru/3.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/3.7/c-api/type.html#c.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.7/c-api/type.html#c.PyTypeObject) можно найти в `Include/object.h`. Для удобства здесь повторяется определение, приведённое там:1617```c18typedef struct _typeobject {19    PyObject_VAR_HEAD20    const char *tp_name; /* Для вывода в формате "<module>.<name>" */21    Py_ssize_t tp_basicsize, tp_itemsize; /* Для выделения памяти */2223    /* Методы для реализации стандартных операций */2425    destructor tp_dealloc;26    printfunc tp_print;27    getattrfunc tp_getattr;28    setattrfunc tp_setattr;29    PyAsyncMethods *tp_as_async; /* ранее известный как tp_compare (Python 2)30                                    или tp_reserved (Python 3) */31    reprfunc tp_repr;3233    /* Наборы методов для стандартных классов */3435    PyNumberMethods *tp_as_number;36    PySequenceMethods *tp_as_sequence;37    PyMappingMethods *tp_as_mapping;3839    /* Дополнительные стандартные операции (здесь для двоичной совместимости) */4041    hashfunc tp_hash;42    ternaryfunc tp_call;43    reprfunc tp_str;44    getattrofunc tp_getattro;45    setattrofunc tp_setattro;4647    /* Функции для доступа к объекту как к буферу ввода/вывода */48    PyBufferProcs *tp_as_buffer;4950    /* Флаги для определения наличия опциональных/расширенных возможностей */51    unsigned long tp_flags;5253    const char *tp_doc; /* Строка документации */5455    /* вызов функции для всех доступных объектов */56    traverseproc tp_traverse;5758    /* удаление ссылок на содержащиеся объекты */59    inquiry tp_clear;6061    /* расширенные сравнения */62    richcmpfunc tp_richcompare;6364    /* включение слабых ссылок */65    Py_ssize_t tp_weaklistoffset;6667    /* Итераторы */68    getiterfunc tp_iter;69    iternextfunc tp_iternext;7071    /* Дескриптор атрибутов и механизмы подклассов */72    struct PyMethodDef *tp_methods;73    struct PyMemberDef *tp_members;74    struct PyGetSetDef *tp_getset;75    struct _typeobject *tp_base;76    PyObject *tp_dict;77    descrgetfunc tp_descr_get;78    descrsetfunc tp_descr_set;79    Py_ssize_t tp_dictoffset;80    initproc tp_init;81    allocfunc tp_alloc;82    newfunc tp_new;83    freefunc tp_free; /* Низкоуровневая процедура освобождения памяти */84    inquiry tp_is_gc; /* Для PyObject_IS_GC */85    PyObject *tp_bases;86    PyObject *tp_mro; /* порядок разрешения методов */87    PyObject *tp_cache;88    PyObject *tp_subclasses;89    PyObject *tp_weaklist;90    destructor tp_del;9192    /* Метка версии кэша атрибутов типа. Добавлено в версии 2.6. */93    unsigned int tp_version_tag;9495    destructor tp_finalize;9697} PyTypeObject;98```99100Структура объекта-типа расширяет структуру [`PyVarObject`](https://python-all.ru/3.7/c-api/structures.html#c.PyVarObject). Поле `ob_size` используется для динамических типов (создаваемых с помощью `type_new()`, обычно вызываемого из объявления класса). Обратите внимание, что [`PyType_Type`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Type) (метатип) инициализирует [`tp_itemsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), что означает, что его экземпляры (т.е. объекты-типы) *должны* иметь поле `ob_size`.101102**[PyObject](https://python-all.ru/3.7/c-api/structures.html#c.PyObject)\* `PyObject._ob_next`**103104**[PyObject](https://python-all.ru/3.7/c-api/structures.html#c.PyObject)\* `PyObject._ob_prev`**105106Эти поля присутствуют только тогда, когда определён макрос `Py_TRACE_REFS`. Их инициализация значением `NULL` выполняется макросом `PyObject_HEAD_INIT`. Для статически выделенных объектов эти поля всегда остаются `NULL`. Для динамически выделенных объектов эти два поля используются для включения объекта в двусвязный список *всех* живых объектов в куче. Это может использоваться для различных целей отладки; в настоящее время единственное применение – вывод объектов, которые остаются живыми в конце выполнения, когда установлена переменная окружения [`PYTHONDUMPREFS`](https://python-all.ru/3.7/using/cmdline.html#envvar-PYTHONDUMPREFS).107108Эти поля не наследуются подтипами.109110**Py\_ssize\_t `PyObject.ob_refcnt`**111112Это счётчик ссылок объекта-типа, инициализируемый значением `1` макросом `PyObject_HEAD_INIT`. Обратите внимание: для статически выделенных объектов-типов экземпляры типа (объекты, у которых `ob_type` указывает обратно на тип) *не* считаются ссылками. Но для динамически выделенных объектов-типов экземпляры *считаются* ссылками.113114Это поле не наследуется подтипами.115116**[PyTypeObject](https://python-all.ru/3.7/c-api/type.html#c.PyTypeObject)\* `PyObject.ob_type`**117118Это тип типа, иными словами, его метатип. Он инициализируется аргументом макроса `PyObject_HEAD_INIT`, и его значением обычно должно быть `&PyType_Type`. Однако для динамически загружаемых модулей расширения, которые должны работать на Windows (по крайней мере), компилятор сообщает, что это недопустимый инициализатор. Поэтому принято передавать `NULL` макросу `PyObject_HEAD_INIT` и явно инициализировать это поле в начале функции инициализации модуля, перед любыми другими действиями. Обычно это делается так:119120```c121Foo_Type.ob_type = &PyType_Type;122```123124Это должно быть сделано до создания любых экземпляров типа. [`PyType_Ready()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Ready) проверяет, равен ли `ob_type` значению `NULL`, и если да, инициализирует его значением поля `ob_type` базового класса. [`PyType_Ready()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Ready) не будет изменять это поле, если оно ненулевое.125126Это поле наследуется подтипами.127128**Py\_ssize\_t `PyVarObject.ob_size`**129130Для статически выделенных объектов-типов это поле должно быть инициализировано нулём. Для динамически выделенных объектов-типов это поле имеет особый внутренний смысл.131132Это поле не наследуется подтипами.133134**const char\* `PyTypeObject.tp_name`**135136Указатель на строку, завершающуюся NUL, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов это должно быть просто имя типа. Если модуль является подмодулем пакета, полное имя пакета является частью полного имени модуля. Например, тип с именем `T`, определённый в модуле `M` в подпакете `Q` пакета `P`, должен иметь инициализатор [`tp_name`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_name) со значением `"P.Q.M.T"`.137138Для динамически выделенных объектов-типов это должно быть просто имя типа, а имя модуля явно хранится в словаре типа как значение для ключа `'__module__'`.139140Для статически выделенных объектов-типов поле tp\_name должно содержать точку. Всё до последней точки становится доступным как атрибут `__module__`, а всё после последней точки – как атрибут [`__name__`](https://python-all.ru/3.7/library/stdtypes.html#definition.__name__).141142Если точка отсутствует, всё поле [`tp_name`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_name) становится доступным как атрибут [`__name__`](https://python-all.ru/3.7/library/stdtypes.html#definition.__name__), а атрибут `__module__` не определён (если только не задан явно в словаре, как описано выше). Это означает, что ваш тип невозможно будет сериализовать с помощью pickle. Кроме того, он не будет отображаться в документации модуля, создаваемой pydoc.143144Это поле не наследуется подтипами.145146**Py\_ssize\_t `PyTypeObject.tp_basicsize`**147148**Py\_ssize\_t `PyTypeObject.tp_itemsize`**149150Эти поля позволяют вычислить размер экземпляров типа в байтах.151152Существует два вида типов: типы с экземплярами фиксированной длины имеют нулевое [`tp_itemsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) поле, типы с экземплярами переменной длины имеют ненулевое [`tp_itemsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) поле. Для типа с экземплярами фиксированной длины все экземпляры имеют одинаковый размер, указанный в [`tp_basicsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).153154Для типа с экземплярами переменной длины экземпляры должны иметь `ob_size` поле, а размер экземпляра равен [`tp_basicsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) плюс N умножить на [`tp_itemsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), где N – «длина» объекта. Значение N обычно хранится в поле `ob_size` экземпляра. Есть исключения: например, int использует отрицательное `ob_size` для обозначения отрицательного числа, и N равно `abs(ob_size)`. Кроме того, наличие поля `ob_size` в структуре экземпляра не означает, что структура экземпляра имеет переменную длину (например, структура для типа списка имеет экземпляры фиксированной длины, но при этом у этих экземпляров есть значимое поле `ob_size`).155156Базовый размер включает поля того экземпляра, которые объявлены макросом [`PyObject_HEAD`](https://python-all.ru/3.7/c-api/structures.html#c.PyObject_HEAD) или [`PyObject_VAR_HEAD`](https://python-all.ru/3.7/c-api/structures.html#c.PyObject_VAR_HEAD) (в зависимости от того, какой из них используется для объявления структуры экземпляра), и он, в свою очередь, включает поля `_ob_prev` и `_ob_next`, если они присутствуют. Это означает, что единственный правильный способ получить инициализатор для [`tp_basicsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) – это использовать оператор `sizeof` для структуры, используемой для объявления макета экземпляра. Базовый размер не включает размер заголовка GC.157158Эти поля наследуются подтипами независимо друг от друга. Если базовый тип имеет ненулевое [`tp_itemsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), обычно небезопасно устанавливать [`tp_itemsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) в другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).159160Замечание о выравнивании: если переменные элементы требуют определённого выравнивания, это должно быть обеспечено значением [`tp_basicsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize). Пример: предположим, тип реализует массив `double`. [`tp_itemsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) равно `sizeof(double)`. Программист должен гарантировать, что [`tp_basicsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) кратно `sizeof(double)` (при условии, что это и есть требование выравнивания для `double`).161162**destructor `PyTypeObject.tp_dealloc`**163164Указатель на функцию деструктора экземпляра. Эта функция должна быть определена, если только тип не гарантирует, что его экземпляры никогда не будут освобождены (как в случае с синглтонами `None` и `Ellipsis`).165166Функция деструктора вызывается макросами [`Py_DECREF()`](https://python-all.ru/3.7/c-api/refcounting.html#c.Py_DECREF) и [`Py_XDECREF()`](https://python-all.ru/3.7/c-api/refcounting.html#c.Py_XDECREF), когда счётчик ссылок становится равным нулю. На этом этапе экземпляр всё ещё существует, но на него нет ссылок. Функция деструктора должна освободить все ссылки, которыми владеет экземпляр, освободить все буферы памяти, принадлежащие экземпляру (используя функцию освобождения, соответствующую функции выделения, которая использовалась для выделения буфера), и, наконец (в качестве последнего действия), вызвать функцию [`tp_free`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_free) типа. Если тип не является подтипируемым (не имеет установленного флага [`Py_TPFLAGS_BASETYPE`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_BASETYPE)), допускается вызывать деаллокатор объекта напрямую, а не через [`tp_free`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_free). Деаллокатором объекта должен быть тот, который использовался для выделения экземпляра; обычно это [`PyObject_Del()`](https://python-all.ru/3.7/c-api/allocation.html#c.PyObject_Del), если экземпляр был выделен с помощью [`PyObject_New()`](https://python-all.ru/3.7/c-api/allocation.html#c.PyObject_New) или `PyObject_VarNew()`, или [`PyObject_GC_Del()`](https://python-all.ru/3.7/c-api/gcsupport.html#c.PyObject_GC_Del), если экземпляр был выделен с помощью [`PyObject_GC_New()`](https://python-all.ru/3.7/c-api/gcsupport.html#c.PyObject_GC_New) или [`PyObject_GC_NewVar()`](https://python-all.ru/3.7/c-api/gcsupport.html#c.PyObject_GC_NewVar).167168Это поле наследуется подтипами.169170**printfunc `PyTypeObject.tp_print`**171172Зарезервированный слот, ранее использовавшийся для форматирования вывода в Python 2.x.173174**getattrfunc `PyTypeObject.tp_getattr`**175176Необязательный указатель на функцию получения строки атрибута.177178Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция [`tp_getattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro), но принимает C-строку вместо объекта строки Python для указания имени атрибута. Сигнатура:179180```c181PyObject * tp_getattr(PyObject *o, char *attr_name);182```183184Это поле наследуется подтипами вместе с [`tp_getattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro): подтип наследует и [`tp_getattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr), и [`tp_getattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr) и [`tp_getattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) подтипа оба равны `NULL`.185186**setattrfunc `PyTypeObject.tp_setattr`**187188Необязательный указатель на функцию для установки и удаления атрибутов.189190Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция [`tp_setattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro), но принимает C-строку вместо объекта строки Python для указания имени атрибута. Сигнатура:191192```c193PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v);194```195196Аргумент *v* устанавливается в `NULL` для удаления атрибута. Это поле наследуется подтипами вместе с [`tp_setattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro): подтип наследует как [`tp_setattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr), так и [`tp_setattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro) от своего базового типа, если [`tp_setattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr) и [`tp_setattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro) подтипа оба равны `NULL`.197198**[PyAsyncMethods](https://python-all.ru/3.7/c-api/typeobj.html#c.PyAsyncMethods)\* `tp_as_async`**199200Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протоколы [ожидаемого объекта](https://python-all.ru/3.7/glossary.html#term-awaitable) и [асинхронного итератора](https://python-all.ru/3.7/glossary.html#term-asynchronous-iterator) на уровне C. Подробнее см. в [Структуры асинхронных объектов](https://python-all.ru/3.7/c-api/typeobj.html#async-structs).201202Новое в версии 3.5: Ранее было известно как `tp_compare` и `tp_reserved`.203204**reprfunc `PyTypeObject.tp_repr`**205206Необязательный указатель на функцию, реализующую встроенную функцию [`repr()`](https://python-all.ru/3.7/library/functions.html#repr).207208Сигнатура такая же, как для [`PyObject_Repr()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Repr); она должна возвращать строку или объект Unicode. В идеале эта функция должна возвращать строку, которая при передаче в [`eval()`](https://python-all.ru/3.7/library/functions.html#eval) в подходящем окружении возвращает объект с тем же значением. Если это невозможно, она должна возвращать строку, начинающуюся с `'<'` и заканчивающуюся `'>'`, из которой можно вывести как тип, так и значение объекта.209210Если это поле не задано, возвращается строка вида `<%s object at %p>`, где `%s` заменяется именем типа, а `%p` – адресом памяти объекта.211212Это поле наследуется подтипами.213214**[PyNumberMethods](https://python-all.ru/3.7/c-api/typeobj.html#c.PyNumberMethods)\* `tp_as_number`**215216Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих числовой протокол. Эти поля описаны в [Структуры числовых объектов](https://python-all.ru/3.7/c-api/typeobj.html#number-structs).217218Поле `tp_as_number` не наследуется, но содержащиеся в нём поля наследуются по отдельности.219220**[PySequenceMethods](https://python-all.ru/3.7/c-api/typeobj.html#c.PySequenceMethods)\* `tp_as_sequence`**221222Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол последовательности. Эти поля описаны в [Структуры объектов-последовательностей](https://python-all.ru/3.7/c-api/typeobj.html#sequence-structs).223224Поле `tp_as_sequence` не наследуется, но содержащиеся в нём поля наследуются по отдельности.225226**[PyMappingMethods](https://python-all.ru/3.7/c-api/typeobj.html#c.PyMappingMethods)\* `tp_as_mapping`**227228Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол отображения. Эти поля описаны в [Структуры объектов-отображений](https://python-all.ru/3.7/c-api/typeobj.html#mapping-structs).229230Поле `tp_as_mapping` не наследуется, но содержащиеся в нём поля наследуются по отдельности.231232**hashfunc `PyTypeObject.tp_hash`**233234Необязательный указатель на функцию, реализующую встроенную функцию [`hash()`](https://python-all.ru/3.7/library/functions.html#hash).235236Сигнатура такая же, как для [`PyObject_Hash()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Hash); она должна возвращать значение типа Py\_hash\_t. Значение `-1` не должно возвращаться как обычное возвращаемое значение; при возникновении ошибки во время вычисления хеша функция должна установить исключение и вернуть `-1`.237238Это поле можно явно установить в [`PyObject_HashNotImplemented()`](https://python-all.ru/3.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/3.7/c-api/object.html#c.PyObject_HashNotImplemented).239240Когда это поле не установлено, попытка получить хеш объекта вызывает [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).241242Это поле наследуется подтипами вместе с [`tp_richcompare`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare): подтип наследует как [`tp_richcompare`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare), так и [`tp_hash`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_hash), если [`tp_richcompare`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа равны `NULL`.243244**ternaryfunc `PyTypeObject.tp_call`**245246Необязательный указатель на функцию, реализующую вызов объекта. Должен быть `NULL`, если объект не вызываем. Сигнатура такая же, как для [`PyObject_Call()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Call).247248Это поле наследуется подтипами.249250**reprfunc `PyTypeObject.tp_str`**251252Необязательный указатель на функцию, реализующую встроенную операцию [`str()`](https://python-all.ru/3.7/library/stdtypes.html#str). (Обратите внимание, что [`str`](https://python-all.ru/3.7/library/stdtypes.html#str) теперь является типом, а [`str()`](https://python-all.ru/3.7/library/stdtypes.html#str) вызывает конструктор этого типа. Этот конструктор вызывает [`PyObject_Str()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Str) для выполнения фактической работы, и [`PyObject_Str()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Str) будет вызывать этот обработчик.)253254Сигнатура такая же, как у [`PyObject_Str()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Str); она должна возвращать строку или объект Unicode. Эта функция должна возвращать «дружественное» строковое представление объекта, поскольку именно это представление будет использоваться, в частности, функцией [`print()`](https://python-all.ru/3.7/library/functions.html#print).255256Если это поле не задано, вызывается [`PyObject_Repr()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Repr) для возврата строкового представления.257258Это поле наследуется подтипами.259260**getattrofunc `PyTypeObject.tp_getattro`**261262Необязательный указатель на функцию получения атрибута.263264Сигнатура такая же, как у [`PyObject_GetAttr()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_GetAttr). Обычно удобно устанавливать это поле в [`PyObject_GenericGetAttr()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_GenericGetAttr), которое реализует обычный способ поиска атрибутов объекта.265266Это поле наследуется подтипами вместе с [`tp_getattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr): подтип наследует и [`tp_getattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr), и [`tp_getattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr) и [`tp_getattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) подтипа оба равны `NULL`.267268**setattrofunc `PyTypeObject.tp_setattro`**269270Необязательный указатель на функцию для установки и удаления атрибутов.271272Сигнатура такая же, как у [`PyObject_SetAttr()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_SetAttr), но необходимо поддерживать установку *v* в `NULL` для удаления атрибута. Обычно удобно устанавливать это поле в [`PyObject_GenericSetAttr()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_GenericSetAttr), которое реализует обычный способ установки атрибутов объекта.273274Это поле наследуется подтипами вместе с [`tp_setattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr): подтип наследует и [`tp_setattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr), и [`tp_setattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro) от своего базового типа, когда [`tp_setattr`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattr) и [`tp_setattro`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_setattro) подтипа оба равны `NULL`.275276**[PyBufferProcs](https://python-all.ru/3.7/c-api/typeobj.html#c.PyBufferProcs)\* `PyTypeObject.tp_as_buffer`**277278Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих буферный интерфейс. Эти поля описаны в [Buffer Object Structures](https://python-all.ru/3.7/c-api/typeobj.html#buffer-structs).279280Поле [`tp_as_buffer`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer) не наследуется, но содержащиеся в нём поля наследуются по отдельности.281282**unsigned long `PyTypeObject.tp_flags`**283284Это поле представляет собой битовую маску различных флагов. Некоторые флаги указывают на изменённую семантику для определённых ситуаций; другие используются для указания того, что определённые поля в объекте типа (или в расширяющих структурах, на которые ссылаются через `tp_as_number`, `tp_as_sequence`, `tp_as_mapping` и [`tp_as_buffer`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer)), которые исторически не всегда присутствовали, теперь действительны; если такой бит флага сброшен, то поля типа, которые он защищает, не должны использоваться и должны считаться имеющими значение ноль или `NULL`.285286Наследование этого поля сложное. Большинство битов флагов наследуются индивидуально, т.е. если у базового типа установлен бит флага, подтип наследует этот бит флага. Биты флагов, относящиеся к расширяющим структурам, строго наследуются, если наследуется расширяющая структура, т.е. значение бита флага базового типа копируется в подтип вместе с указателем на расширяющую структуру. Бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) наследуется вместе с полями [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear), т.е. если бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) сброшен в подтипе, а поля [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) в подтипе существуют и имеют значения `NULL`.287288В настоящее время определены следующие битовые маски; их можно объединять с помощью оператора `|` для получения значения поля [`tp_flags`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_flags). Макрос [`PyType_HasFeature()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_HasFeature) принимает тип и значение флагов, *tp* и *f*, и проверяет, является ли `tp->tp_flags & f` ненулевым.289290#### `Py_TPFLAGS_HEAPTYPE`291292Этот бит устанавливается, когда сам объект типа выделяется в куче. В таком случае поле `ob_type` его экземпляров считается ссылкой на тип, и счётчик ссылок объекта типа увеличивается (INCREF) при создании нового экземпляра и уменьшается (DECREF) при уничтожении экземпляра (это не относится к экземплярам подтипов; только тип, на который ссылается ob\_type экземпляра, получает INCREF или DECREF).293294#### `Py_TPFLAGS_BASETYPE`295296Этот бит устанавливается, когда тип может использоваться как базовый тип другого типа. Если этот бит сброшен, тип не может быть унаследован (аналогично «финальному» классу в Java).297298#### `Py_TPFLAGS_READY`299300Этот бит устанавливается, когда объект типа был полностью инициализирован функцией [`PyType_Ready()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Ready).301302#### `Py_TPFLAGS_READYING`303304Этот бит устанавливается, пока [`PyType_Ready()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Ready) находится в процессе инициализации объекта типа.305306#### `Py_TPFLAGS_HAVE_GC`307308Этот бит устанавливается, когда объект поддерживает сборку мусора. Если бит установлен, экземпляры должны создаваться с помощью [`PyObject_GC_New()`](https://python-all.ru/3.7/c-api/gcsupport.html#c.PyObject_GC_New) и уничтожаться с помощью [`PyObject_GC_Del()`](https://python-all.ru/3.7/c-api/gcsupport.html#c.PyObject_GC_Del). Дополнительная информация – в разделе [Поддержка циклической сборки мусора](https://python-all.ru/3.7/c-api/gcsupport.html#supporting-cycle-detection). Этот бит также означает, что связанные со сборкой мусора поля [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) присутствуют в объекте типа.309310#### `Py_TPFLAGS_DEFAULT`311312Это битовая маска всех битов, относящихся к наличию определённых полей в объекте типа и его структурах расширения. В настоящее время она включает следующие биты: `Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`, `Py_TPFLAGS_HAVE_VERSION_TAG`.313314#### `Py_TPFLAGS_LONG_SUBCLASS`315316#### `Py_TPFLAGS_LIST_SUBCLASS`317318#### `Py_TPFLAGS_TUPLE_SUBCLASS`319320#### `Py_TPFLAGS_BYTES_SUBCLASS`321322#### `Py_TPFLAGS_UNICODE_SUBCLASS`323324#### `Py_TPFLAGS_DICT_SUBCLASS`325326#### `Py_TPFLAGS_BASE_EXC_SUBCLASS`327328#### `Py_TPFLAGS_TYPE_SUBCLASS`329330Эти флаги используются такими функциями, как [`PyLong_Check()`](https://python-all.ru/3.7/c-api/long.html#c.PyLong_Check), для быстрого определения, является ли тип подклассом встроенного типа; такие конкретные проверки выполняются быстрее, чем общая проверка, например [`PyObject_IsInstance()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_IsInstance). Пользовательские типы, наследующие от встроенных, должны иметь соответствующий [`tp_flags`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_flags) установленным, иначе код, взаимодействующий с такими типами, будет вести себя по-разному в зависимости от того, какая проверка используется.331332#### `Py_TPFLAGS_HAVE_FINALIZE`333334Этот бит устанавливается, когда слот [`tp_finalize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_finalize) присутствует в структуре типа.335336Новое в версии 3.4.337338**const char\* `PyTypeObject.tp_doc`**339340Необязательный указатель на C-строку, завершающуюся нулевым символом, содержащую строку документации для этого объекта типа. Это отображается как атрибут `__doc__` у типа и его экземпляров.341342Это поле *не* наследуется подтипами.343344**[traverseproc](https://python-all.ru/3.7/c-api/gcsupport.html#c.traverseproc) `PyTypeObject.tp_traverse`**345346Необязательный указатель на функцию обхода для сборщика мусора. Используется только если установлен флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Дополнительную информацию о схеме сборки мусора Python можно найти в разделе [Поддержка циклической сборки мусора](https://python-all.ru/3.7/c-api/gcsupport.html#supporting-cycle-detection).347348Указатель [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) используется сборщиком мусора для обнаружения циклических ссылок. Типичная реализация функции [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) просто вызывает [`Py_VISIT()`](https://python-all.ru/3.7/c-api/gcsupport.html#c.Py_VISIT) для каждого элемента экземпляра, являющегося объектом Python, которым владеет экземпляр. Например, это функция `local_traverse()` из модуля расширения [`_thread`](https://python-all.ru/3.7/library/_thread.html#module-_thread):349350```c351static int352local_traverse(localobject *self, visitproc visit, void *arg)353{354    Py_VISIT(self->args);355    Py_VISIT(self->kw);356    Py_VISIT(self->dict);357    return 0;358}359```360361Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/3.7/c-api/gcsupport.html#c.Py_VISIT) вызывается только для тех членов, которые могут участвовать в циклических ссылках. Хотя есть также член `self->key`, он может быть только `NULL` или строкой Python и поэтому не может быть частью циклической ссылки.362363С другой стороны, даже если известно, что член никогда не может быть частью цикла, в качестве средства отладки его всё равно можно обойти, чтобы функция [`get_referents()`](https://python-all.ru/3.7/library/gc.html#gc.get_referents) модуля [`gc`](https://python-all.ru/3.7/library/gc.html#module-gc) включила его.364365> **Предупреждение**366>367> При реализации [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) должны обходиться только те члены, которыми экземпляр *владеет* (имея на них сильные ссылки). Например, если объект поддерживает слабые ссылки через слот [`tp_weaklist`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklist), указатель, поддерживающий связный список (на который указывает *tp\_weaklist*), **не** должен обходиться, так как экземпляр не владеет напрямую слабыми ссылками на себя (список слабых ссылок существует для поддержки механизма слабых ссылок, но у экземпляра нет сильной ссылки на элементы внутри него, поскольку им разрешено удаляться, даже если экземпляр всё ещё жив).368369Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/3.7/c-api/gcsupport.html#c.Py_VISIT) требует, чтобы параметры *visit* и *arg* для `local_traverse()` имели именно такие имена; не следует называть их как попало.370371Это поле наследуется подтипами вместе с [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) и флагом [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): флаг, [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) наследуются от базового типа, если они равны нулю в подтипе.372373**[inquiry](https://python-all.ru/3.7/c-api/gcsupport.html#c.inquiry) `PyTypeObject.tp_clear`**374375Необязательный указатель на функцию очистки для сборщика мусора. Используется только если установлен флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).376377Функция-член [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) используется для разрыва циклических ссылок в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности все функции [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) в системе должны совместно разрывать все циклические ссылки. Это тонкий момент, и при любых сомнениях следует предоставить функцию [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear). Например, тип tuple не реализует функцию [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear), поскольку можно доказать, что ни одна циклическая ссылка не может состоять исключительно из кортежей. Поэтому функции [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) других типов должны быть достаточны для разрыва любой циклической ссылки, содержащей кортеж. Это не очевидно, и редко есть веская причина избегать реализации [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear).378379Реализации [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) должны удалять ссылки экземпляра на те его члены, которые могут являться объектами Python, и устанавливать указатели на эти члены в `NULL`, как показано в следующем примере:380381```c382static int383local_clear(localobject *self)384{385    Py_CLEAR(self->key);386    Py_CLEAR(self->args);387    Py_CLEAR(self->kw);388    Py_CLEAR(self->dict);389    return 0;390}391```392393Следует использовать макрос [`Py_CLEAR()`](https://python-all.ru/3.7/c-api/refcounting.html#c.Py_CLEAR), потому что очистка ссылок – это деликатная операция: счётчик ссылок на содержащийся объект не должен уменьшаться до тех пор, пока указатель на содержащийся объект не будет установлен в `NULL`. Это связано с тем, что уменьшение счётчика ссылок может привести к тому, что содержащийся объект станет мусором, вызвав цепочку действий по его освобождению, которая может включать вызов произвольного кода Python (из-за финализаторов или колбэков слабых ссылок, связанных с содержащимся объектом). Если такой код может снова сослаться на *self*, важно, чтобы указатель на содержащийся объект был `NULL` в этот момент, чтобы *self* знал, что содержащийся объект больше не может использоваться. Макрос [`Py_CLEAR()`](https://python-all.ru/3.7/c-api/refcounting.html#c.Py_CLEAR) выполняет операции в безопасном порядке.394395Поскольку цель функций [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) – разрывать циклические ссылки, нет необходимости очищать содержащиеся объекты, такие как строки Python или целые числа Python, которые не могут участвовать в циклических ссылках. С другой стороны, может быть удобно очистить все содержащиеся объекты Python и написать функцию [`tp_dealloc`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dealloc) типа так, чтобы она вызывала [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear).396397Дополнительную информацию о схеме сборки мусора Python можно найти в разделе [Поддержка циклической сборки мусора](https://python-all.ru/3.7/c-api/gcsupport.html#supporting-cycle-detection).398399Это поле наследуется подтипами вместе с [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и флагом [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): флаг, [`tp_traverse`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_clear) наследуются от базового типа, если они равны нулю в подтипе.400401**richcmpfunc `PyTypeObject.tp_richcompare`**402403Необязательный указатель на функцию расширенного сравнения, сигнатура которой `PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)`. Первый параметр гарантированно является экземпляром типа, определённого [`PyTypeObject`](https://python-all.ru/3.7/c-api/type.html#c.PyTypeObject).404405Функция должна возвращать результат сравнения (обычно `Py_True` или `Py_False`). Если сравнение не определено, она должна вернуть `Py_NotImplemented`; если произошла другая ошибка, она должна вернуть `NULL` и установить условие исключения.406407> **Примечание**408>409> Если требуется реализовать тип, для которого имеет смысл только ограниченный набор сравнений (например, `==` и `!=`, но не `<` и др.), следует напрямую возбуждать [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError) в функции расширенного сравнения.410411Это поле наследуется подтипами вместе с [`tp_hash`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_hash): подтип наследует [`tp_richcompare`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_hash), когда [`tp_richcompare`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа оба `NULL`.412413Следующие константы определены для использования в качестве третьего аргумента для [`tp_richcompare`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и для [`PyObject_RichCompare()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_RichCompare):414415| Константа | Сравнение |416| --- | --- |417| `Py_LT` | `<` |418| `Py_LE` | `<=` |419| `Py_EQ` | `==` |420| `Py_NE` | `!=` |421| `Py_GT` | `>` |422| `Py_GE` | `>=` |423424Для упрощения написания функций расширенного сравнения определён следующий макрос:425426#### `PyObject *Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, int op)`427428Возвращает `Py_True` или `Py_False` из функции в зависимости от результата сравнения. VAL\_A и VAL\_B должны быть упорядочиваемыми с помощью операторов сравнения языка C (например, это могут быть значения типа int или float). Третий аргумент задаёт требуемую операцию, как и для [`PyObject_RichCompare()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_RichCompare).429430Счётчик ссылок возвращаемого значения корректно увеличивается.431432В случае ошибки устанавливает исключение и возвращает NULL из функции.433434Добавлено в версии 3.7.435436**Py\_ssize\_t `PyTypeObject.tp_weaklistoffset`**437438Если экземпляры этого типа поддерживают слабые ссылки, это поле больше нуля и содержит смещение в структуре экземпляра до головы списка слабых ссылок (игнорируя заголовок GC, если он присутствует); это смещение используется функциями `PyObject_ClearWeakRefs()` и `PyWeakref_*()`. Структура экземпляра должна включать поле типа [`PyObject*`](https://python-all.ru/3.7/c-api/structures.html#c.PyObject), которое инициализируется значением `NULL`.439440Не путайте это поле с [`tp_weaklist`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklist); это голова списка для слабых ссылок на сам объект типа.441442Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что подтип использует другую голову списка слабых ссылок, нежели базовый тип. Поскольку голова списка всегда находится через [`tp_weaklistoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset), это не должно быть проблемой.443444Если тип, определённый с помощью оператора class, не содержит объявления [`__slots__`](https://python-all.ru/3.7/reference/datamodel.html#object.__slots__), и ни один из его базовых типов не поддерживает слабые ссылки, тип делается доступным для слабых ссылок: в компоновку экземпляра добавляется слот заголовка списка слабых ссылок, и [`tp_weaklistoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) устанавливается на смещение этого слота.445446Если объявление `__slots__` типа содержит слот с именем `__weakref__`, этот слот становится заголовком списка слабых ссылок для экземпляров типа, а его смещение сохраняется в поле [`tp_weaklistoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) типа.447448Если объявление `__slots__` типа не содержит слота с именем `__weakref__`, тип наследует значение [`tp_weaklistoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) от своего базового типа.449450**getiterfunc `PyTypeObject.tp_iter`**451452Необязательный указатель на функцию, возвращающую итератор для объекта. Его наличие обычно указывает на то, что экземпляры этого типа являются итерируемыми (хотя последовательности могут быть итерируемыми и без этой функции).453454Эта функция имеет ту же сигнатуру, что и [`PyObject_GetIter()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_GetIter).455456Это поле наследуется подтипами.457458**iternextfunc `PyTypeObject.tp_iternext`**459460Необязательный указатель на функцию, возвращающую следующий элемент итератора. Когда итератор исчерпан, она должна вернуть `NULL`; при этом исключение [`StopIteration`](https://python-all.ru/3.7/library/exceptions.html#StopIteration) может быть установлено, а может и нет. При возникновении другой ошибки она также должна вернуть `NULL`. Наличие этой функции указывает на то, что экземпляры данного типа являются итераторами.461462Типы-итераторы также должны определять функцию [`tp_iter`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_iter), и эта функция должна возвращать сам экземпляр итератора (не новый экземпляр итератора).463464Эта функция имеет ту же сигнатуру, что и [`PyIter_Next()`](https://python-all.ru/3.7/c-api/iter.html#c.PyIter_Next).465466Это поле наследуется подтипами.467468**struct [PyMethodDef](https://python-all.ru/3.7/c-api/structures.html#c.PyMethodDef)\* `PyTypeObject.tp_methods`**469470Необязательный указатель на статический массив структур [`PyMethodDef`](https://python-all.ru/3.7/c-api/structures.html#c.PyMethodDef), завершающийся `NULL`, объявляющий обычные методы этого типа.471472Для каждой записи в массиве в словарь типа добавляется запись (см. [`tp_dict`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже), содержащая дескриптор метода.473474Это поле не наследуется подтипами (методы наследуются через другой механизм).475476**struct [PyMemberDef](https://python-all.ru/3.7/c-api/structures.html#c.PyMemberDef)\* `PyTypeObject.tp_members`**477478Необязательный указатель на статический массив [`PyMemberDef`](https://python-all.ru/3.7/c-api/structures.html#c.PyMemberDef) структур, завершающийся `NULL`, объявляющий обычные элементы данных (поля или слоты) экземпляров этого типа.479480Для каждой записи в массиве в словарь типа добавляется запись, содержащая дескриптор члена (см. [`tp_dict`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже).481482Это поле не наследуется подтипами (члены наследуются через другой механизм).483484**struct [PyGetSetDef](https://python-all.ru/3.7/c-api/structures.html#c.PyGetSetDef)\* `PyTypeObject.tp_getset`**485486Необязательный указатель на статический массив [`PyGetSetDef`](https://python-all.ru/3.7/c-api/structures.html#c.PyGetSetDef) структур, завершающийся `NULL`, объявляющий вычисляемые атрибуты экземпляров этого типа.487488Для каждой записи в массиве в словарь типа добавляется запись, содержащая дескриптор getset (см. [`tp_dict`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже).489490Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).491492**[PyTypeObject](https://python-all.ru/3.7/c-api/type.html#c.PyTypeObject)\* `PyTypeObject.tp_base`**493494Необязательный указатель на базовый тип, от которого наследуются свойства типа. На этом уровне поддерживается только одиночное наследование; множественное наследование требует динамического создания объекта типа вызовом метатипа.495496Это поле не наследуется подтипами (очевидно), но по умолчанию оно равно `&PyBaseObject_Type` (которое программистам Python известно как тип [`object`](https://python-all.ru/3.7/library/functions.html#object)).497498**[PyObject](https://python-all.ru/3.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_dict`**499500Словарь типа сохраняется здесь с помощью [`PyType_Ready()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Ready).501502Это поле обычно должно быть инициализировано значением `NULL` до вызова PyType\_Ready; его также можно инициализировать словарём с начальными атрибутами типа. После того, как [`PyType_Ready()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Ready) инициализирует тип, дополнительные атрибуты можно добавлять в этот словарь только если они не соответствуют перегруженным операциям (например, [`__add__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__add__)).503504Это поле не наследуется подтипами (хотя определённые здесь атрибуты наследуются через другой механизм).505506> **Предупреждение**507>508> Небезопасно использовать [`PyDict_SetItem()`](https://python-all.ru/3.7/c-api/dict.html#c.PyDict_SetItem) на или иным образом изменять [`tp_dict`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dict) с помощью C-API словаря.509510**descrgetfunc `PyTypeObject.tp_descr_get`**511512Необязательный указатель на функцию «descriptor get».513514Сигнатура функции:515516```c517PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);518```519520Это поле наследуется подтипами.521522**descrsetfunc `PyTypeObject.tp_descr_set`**523524Необязательный указатель на функцию для установки и удаления значения дескриптора.525526Сигнатура функции:527528```c529int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);530```531532Аргумент *значение* устанавливается в `NULL` для удаления значения. Это поле наследуется подтипами.533534**Py\_ssize\_t `PyTypeObject.tp_dictoffset`**535536Если экземпляры этого типа имеют словарь, содержащий переменные экземпляра, это поле не равно нулю и содержит смещение в структуре экземпляра для словаря переменных экземпляра; это смещение используется [`PyObject_GenericGetAttr()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_GenericGetAttr).537538Не путайте это поле с [`tp_dict`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dict); это словарь для атрибутов самого объекта типа.539540Если значение этого поля больше нуля, оно задаёт смещение от начала структуры экземпляра. Если значение меньше нуля, оно задаёт смещение от *конца* структуры экземпляра. Использование отрицательного смещения обходится дороже, и его следует применять только в тех случаях, когда структура экземпляра содержит часть переменной длины. Это используется, например, для добавления словаря переменных экземпляра в подтипы [`str`](https://python-all.ru/3.7/library/stdtypes.html#str) или [`tuple`](https://python-all.ru/3.7/library/stdtypes.html#tuple). Обратите внимание, что поле [`tp_basicsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) должно учитывать словарь, добавленный в конец в этом случае, даже если словарь не входит в базовую компоновку объекта. В системе с размером указателя 4 байта [`tp_dictoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) должно быть установлено в `-4`, чтобы указать, что словарь находится в самом конце структуры.541542Реальное смещение словаря в экземпляре можно вычислить из отрицательного [`tp_dictoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) следующим образом:543544```c545dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset546if dictoffset is not aligned on sizeof(void*):547    round up to sizeof(void*)548```549550где [`tp_basicsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize), [`tp_itemsize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) и [`tp_dictoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) берутся из объекта типа, а `ob_size` берётся из экземпляра. Абсолютное значение берётся, потому что целые числа используют знак `ob_size` для хранения знака числа. (Никогда не требуется выполнять это вычисление самостоятельно; оно делается за вас функцией `_PyObject_GetDictPtr()`.)551552Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что экземпляры подтипа хранят словарь по другому смещению, нежели базовый тип. Поскольку словарь всегда находится через [`tp_dictoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset), это не должно вызывать проблем.553554Если тип, определённый с помощью оператора class, не содержит объявления [`__slots__`](https://python-all.ru/3.7/reference/datamodel.html#object.__slots__), и ни один из его базовых типов не имеет словаря переменных экземпляра, в компоновку экземпляра добавляется слот словаря, а [`tp_dictoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) устанавливается на смещение этого слота.555556Если тип, определённый с помощью оператора class, содержит объявление `__slots__`, тот тип наследует значение [`tp_dictoffset`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) от своего базового типа.557558(Добавление слота с именем [`__dict__`](https://python-all.ru/3.7/library/stdtypes.html#object.__dict__) в объявление `__slots__` не даёт ожидаемого эффекта, а только вызывает путаницу. Возможно, эту возможность стоит добавить как отдельную функцию, подобно `__weakref__`.)559560**initproc `PyTypeObject.tp_init`**561562Необязательный указатель на функцию инициализации экземпляра.563564Эта функция соответствует методу [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__) классов. Как и [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__), можно создать экземпляр без вызова [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__), и можно переинициализировать экземпляр, вызвав его метод [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__) ещё раз.565566Сигнатура функции:567568```c569int tp_init(PyObject *self, PyObject *args, PyObject *kwds)570```571572Аргумент self – это инициализируемый экземпляр; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова [`__init__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__init__).573574Функция [`tp_init`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_init), если она не `NULL`, вызывается при обычном создании экземпляра через вызов его типа, после того как функция [`tp_new`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_new) типа вернула экземпляр этого типа. Если функция [`tp_new`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_new) возвращает экземпляр другого типа, не являющегося подтипом исходного, функция [`tp_init`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_init) не вызывается; если [`tp_new`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_new) возвращает экземпляр подтипа исходного типа, вызывается [`tp_init`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_init) подтипа.575576Это поле наследуется подтипами.577578**allocfunc `PyTypeObject.tp_alloc`**579580Необязательный указатель на функцию выделения экземпляра.581582Сигнатура функции:583584```c585PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)586```587588Назначение этой функции – разделить выделение памяти и её инициализацию. Она должна возвращать указатель на блок памяти достаточной длины для экземпляра, с подходящим выравниванием и обнулённый, но с `ob_refcnt`, установленным в `1`, и `ob_type`, установленным в аргумент типа. Если [`tp_itemsize`](https://python-all.ru/3.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/3.7/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).589590Эту функцию не следует использовать для какой-либо другой инициализации экземпляра, в том числе для выделения дополнительной памяти; это должно выполняться с помощью [`tp_new`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_new).591592Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными выражением class); в последних это поле всегда устанавливается в [`PyType_GenericAlloc()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_GenericAlloc), чтобы принудительно использовать стандартную стратегию выделения в куче. Это также рекомендуемое значение для статически определённых типов.593594**newfunc `PyTypeObject.tp_new`**595596Необязательный указатель на функцию создания экземпляра.597598Если для данного типа эта функция равна `NULL`, то такой тип нельзя вызвать для создания новых экземпляров; предполагается, что существует другой способ создания экземпляров, например, фабричная функция.599600Сигнатура функции:601602```c603PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)604```605606Аргумент subtype – это тип создаваемого объекта; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова типа. Обратите внимание, что subtype не обязан совпадать с типом, для которого вызывается функция [`tp_new`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_new); это может быть подтип этого типа (но не произвольный тип).607608Функция [`tp_new`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_new) должна вызывать `subtype->tp_alloc(subtype, nitems)` для выделения памяти под объект, а затем выполнять лишь минимально необходимую инициализацию. Инициализацию, которую можно безопасно пропустить или повторить, следует помещать в обработчик [`tp_init`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_init). Хорошее эмпирическое правило: для неизменяемых типов вся инициализация должна выполняться в [`tp_new`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_new), а для изменяемых типов большую часть инициализации лучше отложить до [`tp_init`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_init).609610Это поле наследуется подтипами, за исключением статических типов, у которых [`tp_base`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_base) равно `NULL` или `&PyBaseObject_Type`.611612**destructor `PyTypeObject.tp_free`**613614Необязательный указатель на функцию освобождения экземпляра. Её сигнатура: `freefunc`:615616```c617void tp_free(void *)618```619620Инициализатор, совместимый с этой сигнатурой: [`PyObject_Free()`](https://python-all.ru/3.7/c-api/memory.html#c.PyObject_Free).621622Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными выражением class); в последних это поле устанавливается в освободитель, подходящий для [`PyType_GenericAlloc()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_GenericAlloc) и значения бита флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).623624**[inquiry](https://python-all.ru/3.7/c-api/gcsupport.html#c.inquiry) `PyTypeObject.tp_is_gc`**625626Необязательный указатель на функцию, вызываемую сборщиком мусора.627628Сборщику мусора необходимо знать, подлежит ли данный объект сборке или нет. Обычно достаточно посмотреть на поле [`tp_flags`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_flags) типа объекта и проверить бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Но некоторые типы имеют смесь статически и динамически выделенных экземпляров, причём статически выделенные экземпляры не подлежат сборке. Таким типам следует определить эту функцию; она должна возвращать `1` для собираемого экземпляра и `0` для несобираемого. Сигнатура:629630```c631int tp_is_gc(PyObject *self)632```633634(Единственный пример этого – сами типы. Метатип, [`PyType_Type`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Type), определяет эту функцию, чтобы различать статически и динамически выделенные типы.)635636Это поле наследуется подтипами.637638**[PyObject](https://python-all.ru/3.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_bases`**639640Кортеж базовых типов.641642Это устанавливается для типов, созданных с помощью оператора class. Для статически определённых типов это должно быть `NULL`.643644Это поле не наследуется.645646**[PyObject](https://python-all.ru/3.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_mro`**647648Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая [`object`](https://python-all.ru/3.7/library/functions.html#object), в порядке разрешения методов (MRO).649650Это поле не наследуется; оно вычисляется заново с помощью [`PyType_Ready()`](https://python-all.ru/3.7/c-api/type.html#c.PyType_Ready).651652**destructor `PyTypeObject.tp_finalize`**653654Необязательный указатель на функцию финализации экземпляра. Её сигнатура: `destructor`:655656```c657void tp_finalize(PyObject *)658```659660Если [`tp_finalize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_finalize) установлен, интерпретатор вызывает его один раз при финализации экземпляра. Он вызывается либо сборщиком мусора (если экземпляр является частью изолированного цикла ссылок), либо непосредственно перед освобождением объекта. В любом случае гарантируется, что он будет вызван до попытки разорвать циклы ссылок, что обеспечивает нахождение объекта в корректном состоянии.661662[`tp_finalize`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_finalize) не должен изменять текущий статус исключения; поэтому рекомендуемый способ написания нетривиального финализатора:663664```c665static void666local_finalize(PyObject *self)667{668    PyObject *error_type, *error_value, *error_traceback;669670    /* Сохранить текущее исключение, если оно есть. */671    PyErr_Fetch(&error_type, &error_value, &error_traceback);672673    /* ... */674675    /* Восстановить сохранённое исключение. */676    PyErr_Restore(error_type, error_value, error_traceback);677}678```679680Чтобы это поле учитывалось (даже при наследовании), необходимо также установить бит флагов [`Py_TPFLAGS_HAVE_FINALIZE`](https://python-all.ru/3.7/c-api/typeobj.html#Py_TPFLAGS_HAVE_FINALIZE).681682Это поле наследуется подтипами.683684Новое в версии 3.4.685686> **См. также**687>688> «Безопасная финализация объектов» ([**PEP 442**](https://python-all.ru/3.7/c-api/typeobj.html))689690**[PyObject](https://python-all.ru/3.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_cache`**691692Не используется. Не наследуется. Только для внутреннего использования.693694**[PyObject](https://python-all.ru/3.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_subclasses`**695696Список слабых ссылок на подклассы. Не наследуется. Только для внутреннего использования.697698**[PyObject](https://python-all.ru/3.7/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_weaklist`**699700Голова списка слабых ссылок для слабых ссылок на этот объект типа. Не наследуется. Только для внутреннего использования.701702Остальные поля определены только в том случае, если определён макрос проверки функциональности `COUNT_ALLOCS`, и предназначены исключительно для внутреннего использования. Они описаны здесь для полноты. Ни одно из этих полей не наследуется подтипами.703704**Py\_ssize\_t `PyTypeObject.tp_allocs`**705706Количество выделений памяти.707708**Py\_ssize\_t `PyTypeObject.tp_frees`**709710Количество освобождений.711712**Py\_ssize\_t `PyTypeObject.tp_maxalloc`**713714Максимальное количество одновременно выделенных объектов.715716**[PyTypeObject](https://python-all.ru/3.7/c-api/type.html#c.PyTypeObject)\* `PyTypeObject.tp_next`**717718Указатель на следующий объект типа с ненулевым полем [`tp_allocs`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyTypeObject.tp_allocs).719720Также следует отметить, что в Python со сборкой мусора tp\_dealloc может вызываться из любого потока Python, а не только из того, который создал объект (если объект становится частью цикла подсчёта ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Это не проблема для вызовов Python API, поскольку поток, в котором вызывается tp\_dealloc, будет владеть глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект, в свою очередь, уничтожает объекты из какой-либо другой библиотеки C или C++, следует соблюдать осторожность, чтобы убедиться, что уничтожение этих объектов в потоке, вызвавшем tp\_dealloc, не нарушит никаких предположений библиотеки.721722# Структуры числовых объектов723724**`PyNumberMethods`**725726Эта структура содержит указатели на функции, которые объект использует для реализации числового протокола. Каждая функция используется одноимённой функцией, описанной в разделе [Числовой протокол](https://python-all.ru/3.7/c-api/number.html#number).727728Вот определение структуры:729730```c731typedef struct {732     binaryfunc nb_add;733     binaryfunc nb_subtract;734     binaryfunc nb_multiply;735     binaryfunc nb_remainder;736     binaryfunc nb_divmod;737     ternaryfunc nb_power;738     unaryfunc nb_negative;739     unaryfunc nb_positive;740     unaryfunc nb_absolute;741     inquiry nb_bool;742     unaryfunc nb_invert;743     binaryfunc nb_lshift;744     binaryfunc nb_rshift;745     binaryfunc nb_and;746     binaryfunc nb_xor;747     binaryfunc nb_or;748     unaryfunc nb_int;749     void *nb_reserved;750     unaryfunc nb_float;751752     binaryfunc nb_inplace_add;753     binaryfunc nb_inplace_subtract;754     binaryfunc nb_inplace_multiply;755     binaryfunc nb_inplace_remainder;756     ternaryfunc nb_inplace_power;757     binaryfunc nb_inplace_lshift;758     binaryfunc nb_inplace_rshift;759     binaryfunc nb_inplace_and;760     binaryfunc nb_inplace_xor;761     binaryfunc nb_inplace_or;762763     binaryfunc nb_floor_divide;764     binaryfunc nb_true_divide;765     binaryfunc nb_inplace_floor_divide;766     binaryfunc nb_inplace_true_divide;767768     unaryfunc nb_index;769770     binaryfunc nb_matrix_multiply;771     binaryfunc nb_inplace_matrix_multiply;772} PyNumberMethods;773```774775> **Примечание**776>777> Бинарные и тернарные функции должны проверять тип всех своих операндов и выполнять необходимые преобразования (хотя бы один из операндов должен быть экземпляром определяемого типа). Если операция не определена для данных операндов, бинарные и тернарные функции должны вернуть `Py_NotImplemented`; если произошла другая ошибка, они должны вернуть `NULL` и установить исключение.778779> **Примечание**780>781> Поле `nb_reserved` всегда должно быть `NULL`. Ранее оно называлось `nb_long` и было переименовано в Python 3.0.1.782783# Структуры объектов отображения784785**`PyMappingMethods`**786787Эта структура хранит указатели на функции, которые объект использует для реализации протокола отображения. Она содержит три члена:788789**lenfunc `PyMappingMethods.mp_length`**790791Эта функция используется [`PyMapping_Size()`](https://python-all.ru/3.7/c-api/mapping.html#c.PyMapping_Size) и [`PyObject_Size()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Size) и имеет ту же сигнатуру. Этот слот может быть установлен в `NULL`, если у объекта нет определённой длины.792793**binaryfunc `PyMappingMethods.mp_subscript`**794795Эта функция используется [`PyObject_GetItem()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_GetItem) и [`PySequence_GetSlice()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_GetSlice) и имеет ту же сигнатуру, что и `PyObject_GetItem()`. Этот слот должен быть заполнен, чтобы функция [`PyMapping_Check()`](https://python-all.ru/3.7/c-api/mapping.html#c.PyMapping_Check) возвращала `1`; в противном случае он может быть `NULL` .796797**objobjargproc `PyMappingMethods.mp_ass_subscript`**798799Эта функция используется [`PyObject_SetItem()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_SetItem), [`PyObject_DelItem()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_DelItem), `PyObject_SetSlice()` и `PyObject_DelSlice()`. У неё та же сигнатура, что и у `PyObject_SetItem()`, но *v* также может быть установлен в `NULL` для удаления элемента. Если этот слот равен `NULL`, объект не поддерживает присваивание и удаление элементов.800801# Структуры объектов последовательностей802803**`PySequenceMethods`**804805Эта структура содержит указатели на функции, которые объект использует для реализации протокола последовательности.806807**lenfunc `PySequenceMethods.sq_length`**808809Эта функция используется [`PySequence_Size()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_Size) и [`PyObject_Size()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_Size) и имеет ту же сигнатуру. Она также используется для обработки отрицательных индексов через слоты [`sq_item`](https://python-all.ru/3.7/c-api/typeobj.html#c.PySequenceMethods.sq_item) и [`sq_ass_item`](https://python-all.ru/3.7/c-api/typeobj.html#c.PySequenceMethods.sq_ass_item).810811**binaryfunc `PySequenceMethods.sq_concat`**812813Эта функция используется [`PySequence_Concat()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_Concat) и имеет ту же сигнатуру. Она также используется оператором `+` после попытки численного сложения через слот `nb_add`.814815**ssizeargfunc `PySequenceMethods.sq_repeat`**816817Эта функция используется [`PySequence_Repeat()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_Repeat) и имеет ту же сигнатуру. Она также используется оператором `*` после попытки численного умножения через слот `nb_multiply`.818819**ssizeargfunc `PySequenceMethods.sq_item`**820821Эта функция используется [`PySequence_GetItem()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_GetItem) и имеет ту же сигнатуру. Она также используется [`PyObject_GetItem()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_GetItem) после попытки индексирования через слот [`mp_subscript`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyMappingMethods.mp_subscript). Этот слот должен быть заполнен, чтобы функция [`PySequence_Check()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_Check) возвращала `1`; в противном случае он может быть `NULL`.822823Отрицательные индексы обрабатываются следующим образом: если слот `sq_length`\\nзаполнен, он вызывается, и длина последовательности используется для вычисления положительного\\nиндекса, который передаётся в `sq_item`. Если `sq_length` равно `NULL`,\\nиндекс передаётся функции как есть.824825**ssizeobjargproc `PySequenceMethods.sq_ass_item`**826827Эта функция используется [`PySequence_SetItem()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_SetItem) и имеет ту же сигнатуру. Она также используется [`PyObject_SetItem()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_SetItem) и [`PyObject_DelItem()`](https://python-all.ru/3.7/c-api/object.html#c.PyObject_DelItem) после попытки присваивания и удаления элемента через слот [`mp_ass_subscript`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyMappingMethods.mp_ass_subscript). Этот слот может быть оставлен равным `NULL`, если объект не поддерживает присваивание и удаление элементов.828829**objobjproc `PySequenceMethods.sq_contains`**830831Эта функция может использоваться [`PySequence_Contains()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_Contains) и имеет ту же сигнатуру. Этот слот может быть оставлен равным `NULL`; в этом случае `PySequence_Contains()` просто проходит по последовательности, пока не найдёт совпадение.832833**binaryfunc `PySequenceMethods.sq_inplace_concat`**834835Эта функция используется [`PySequence_InPlaceConcat()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_InPlaceConcat) и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его. Этот слот может быть оставлен равным `NULL`; в этом случае `PySequence_InPlaceConcat()` будет использовать [`PySequence_Concat()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_Concat) как запасной вариант. Она также используется расширенным присваиванием `+=` после попытки численного сложения на месте через слот `nb_inplace_add`.836837**ssizeargfunc `PySequenceMethods.sq_inplace_repeat`**838839Эта функция используется [`PySequence_InPlaceRepeat()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_InPlaceRepeat) и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его. Этот слот может быть оставлен равным `NULL`; в этом случае `PySequence_InPlaceRepeat()` будет использовать [`PySequence_Repeat()`](https://python-all.ru/3.7/c-api/sequence.html#c.PySequence_Repeat) как запасной вариант. Она также используется расширенным присваиванием `*=` после попытки численного умножения на месте через слот `nb_inplace_multiply`.840841# Структуры объектов буфера842843**`PyBufferProcs`**844845Эта структура содержит указатели на функции, необходимые для [протокола буфера](https://python-all.ru/3.7/c-api/buffer.html#bufferobjects). Протокол определяет, как объект-экспортёр может предоставлять свои внутренние данные объектам-потребителям.846847**getbufferproc `PyBufferProcs.bf_getbuffer`**848849Сигнатура этой функции:850851```c852int (PyObject *exporter, Py_buffer *view, int flags);853```854855Обрабатывает запрос к *экспортёру* на заполнение *представления* в соответствии с *флагами*. За исключением пункта (3), реализация этой функции ОБЯЗАНА выполнить следующие шаги:8568571. Проверить, можно ли удовлетворить запрос. Если нет, возбудить `PyExc_BufferError`, установить `view->obj` в `NULL` и вернуть `-1`.8582. Заполнить запрошенные поля.8593. Увеличить внутренний счётчик числа экспортов.8604. Установить `view->obj` в *экспортёр* и увеличить `view->obj`.8615. Вернуть `0`.862863Если *экспортёр* является частью цепочки или дерева поставщиков буферов, можно использовать две основные схемы:864865- Повторный экспорт: каждый элемент дерева выступает в роли экспортирующего объекта и устанавливает `view->obj` в новую ссылку на себя.866- Перенаправление: запрос буфера перенаправляется корневому объекту дерева. Здесь `view->obj` будет новой ссылкой на корневой объект.867868Отдельные поля *представления* описаны в разделе [Структура буфера](https://python-all.ru/3.7/c-api/buffer.html#buffer-structure), правила, как экспортёр должен реагировать на конкретные запросы – в разделе [Типы запросов буфера](https://python-all.ru/3.7/c-api/buffer.html#buffer-request-types).869870Вся память, на которую указывает структура [`Py_buffer`](https://python-all.ru/3.7/c-api/buffer.html#c.Py_buffer), принадлежит экспортёру и должна оставаться действительной, пока есть хотя бы один потребитель. [`format`](https://python-all.ru/3.7/c-api/buffer.html#c.Py_buffer.format), [`shape`](https://python-all.ru/3.7/c-api/buffer.html#c.Py_buffer.shape), [`strides`](https://python-all.ru/3.7/c-api/buffer.html#c.Py_buffer.strides), [`suboffsets`](https://python-all.ru/3.7/c-api/buffer.html#c.Py_buffer.suboffsets) и [`internal`](https://python-all.ru/3.7/c-api/buffer.html#c.Py_buffer.internal) доступны потребителю только для чтения.871872[`PyBuffer_FillInfo()`](https://python-all.ru/3.7/c-api/buffer.html#c.PyBuffer_FillInfo) предоставляет простой способ предоставления простого байтового буфера, корректно обрабатывая все типы запросов.873874[`PyObject_GetBuffer()`](https://python-all.ru/3.7/c-api/buffer.html#c.PyObject_GetBuffer) – это интерфейс для потребителя, который оборачивает эту функцию.875876**releasebufferproc `PyBufferProcs.bf_releasebuffer`**877878Сигнатура этой функции:879880```c881void (PyObject *exporter, Py_buffer *view);882```883884Обрабатывает запрос на освобождение ресурсов буфера. Если никакие ресурсы освобождать не нужно, [`PyBufferProcs.bf_releasebuffer`](https://python-all.ru/3.7/c-api/typeobj.html#c.PyBufferProcs.bf_releasebuffer) может быть `NULL`. В противном случае стандартная реализация этой функции выполнит следующие необязательные шаги:8858861. Уменьшить внутренний счётчик числа экспортов.8872. Если счётчик равен `0`, освободить всю память, связанную с *представлением*.888889Экспортёр ОБЯЗАН использовать поле [`internal`](https://python-all.ru/3.7/c-api/buffer.html#c.Py_buffer.internal) для отслеживания ресурсов, специфичных для буфера. Гарантируется, что это поле остаётся постоянным, в то время как потребитель МОЖЕТ передавать копию исходного буфера в качестве аргумента *view*.890891Эта функция НЕ ДОЛЖНА уменьшать `view->obj`, так как это делается автоматически в [`PyBuffer_Release()`](https://python-all.ru/3.7/c-api/buffer.html#c.PyBuffer_Release) (такая схема полезна для разрыва циклических ссылок).892893[`PyBuffer_Release()`](https://python-all.ru/3.7/c-api/buffer.html#c.PyBuffer_Release) – это интерфейс для потребителя, который оборачивает эту функцию.894895# Асинхронные структуры объектов896897Новое в версии 3.5.898899**`PyAsyncMethods`**900901Эта структура содержит указатели на функции, необходимые для реализации объектов [ожидаемый объект](https://python-all.ru/3.7/glossary.html#term-awaitable) и [асинхронный итератор](https://python-all.ru/3.7/glossary.html#term-asynchronous-iterator).902903Вот определение структуры:904905```c906typedef struct {907    unaryfunc am_await;908    unaryfunc am_aiter;909    unaryfunc am_anext;910} PyAsyncMethods;911```912913**unaryfunc `PyAsyncMethods.am_await`**914915Сигнатура этой функции:916917```c918PyObject *am_await(PyObject *self)919```920921Возвращаемый объект должен быть итератором, то есть [`PyIter_Check()`](https://python-all.ru/3.7/c-api/iter.html#c.PyIter_Check) должен возвращать `1` для него.922923Этот слот может быть установлен в `NULL`, если объект не является [ожидаемым объектом](https://python-all.ru/3.7/glossary.html#term-awaitable).924925**unaryfunc `PyAsyncMethods.am_aiter`**926927Сигнатура этой функции:928929```c930PyObject *am_aiter(PyObject *self)931```932933Должен возвращать [ожидаемый](https://python-all.ru/3.7/glossary.html#term-awaitable) объект. Подробнее см. [`__anext__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__anext__).934935Этот слот может быть установлен в `NULL`, если объект не реализует протокол асинхронной итерации.936937**unaryfunc `PyAsyncMethods.am_anext`**938939Сигнатура этой функции:940941```c942PyObject *am_anext(PyObject *self)943```944945Должен возвращать объект [ожидаемый объект](https://python-all.ru/3.7/glossary.html#term-awaitable). Подробности см. в [`__anext__()`](https://python-all.ru/3.7/reference/datamodel.html#object.__anext__). Этот слот может быть установлен в `NULL`.946