typeobj.md · Markdown – Документация Python
Документация Python неофициальный перевод

typeobj.md

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

1> **Источник:** https://python-all.ru/3.4/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.4/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.4/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    void *tp_reserved; /* ранее известный как tp_compare */30    reprfunc tp_repr;3132    /* Наборы методов для стандартных классов */3334    PyNumberMethods *tp_as_number;35    PySequenceMethods *tp_as_sequence;36    PyMappingMethods *tp_as_mapping;3738    /* Дополнительные стандартные операции (здесь для двоичной совместимости) */3940    hashfunc tp_hash;41    ternaryfunc tp_call;42    reprfunc tp_str;43    getattrofunc tp_getattro;44    setattrofunc tp_setattro;4546    /* Функции для доступа к объекту как к буферу ввода/вывода */47    PyBufferProcs *tp_as_buffer;4849    /* Флаги для определения наличия опциональных/расширенных возможностей */50    unsigned long tp_flags;5152    const char *tp_doc; /* Строка документации */5354    /* вызов функции для всех доступных объектов */55    traverseproc tp_traverse;5657    /* удаление ссылок на содержащиеся объекты */58    inquiry tp_clear;5960    /* расширенные сравнения */61    richcmpfunc tp_richcompare;6263    /* включение слабых ссылок */64    Py_ssize_t 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    Py_ssize_t 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;89    destructor tp_del;9091    /* Метка версии кэша атрибутов типа. Добавлено в версии 2.6. */92    unsigned int tp_version_tag;9394    destructor tp_finalize;9596} PyTypeObject;97```9899The type object structure extends the [`PyVarObject`](https://python-all.ru/3.4/c-api/structures.html#c.PyVarObject) structure. The `ob_size` field is used for dynamic types (created by `type_new()`, usually called from a class statement). Note that [`PyType_Type`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Type) (the metatype) initializes [`tp_itemsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), which means that its instances (i.e. type objects) *must* have the `ob_size` field.100101**[PyObject](https://python-all.ru/3.4/c-api/structures.html#c.PyObject)\* `PyObject._ob_next`**102103**[PyObject](https://python-all.ru/3.4/c-api/structures.html#c.PyObject)\* `PyObject._ob_prev`**104105Эти поля присутствуют только тогда, когда определён макрос `Py_TRACE_REFS`. Их инициализацию значением *NULL* берёт на себя макрос `PyObject_HEAD_INIT`. Для статически выделенных объектов эти поля всегда остаются *NULL*. Для динамически выделенных объектов эти два поля используются для включения объекта в двусвязный список *всех* живых объектов в куче. Это может использоваться для различных целей отладки; в настоящее время единственное применение – вывод объектов, которые всё ещё живы в конце выполнения, когда установлена переменная окружения [`PYTHONDUMPREFS`](https://python-all.ru/3.4/using/cmdline.html#envvar-PYTHONDUMPREFS).106107Эти поля не наследуются подтипами.108109**Py\_ssize\_t `PyObject.ob_refcnt`**110111Это счётчик ссылок объекта типа, инициализированный значением `1` макросом `PyObject_HEAD_INIT`. Обратите внимание, что для статически выделенных объектов типов экземпляры типа (объекты, у которых `ob_type` указывает обратно на тип) *не* считаются ссылками. Но для динамически выделенных объектов типов экземпляры *всё же* считаются ссылками.112113Это поле не наследуется подтипами.114115**[PyTypeObject](https://python-all.ru/3.4/c-api/type.html#c.PyTypeObject)\* `PyObject.ob_type`**116117Это тип типа, иными словами, его метатип. Он инициализируется аргументом макроса `PyObject_HEAD_INIT`, и его значением обычно должно быть `&PyType_Type`. Однако для динамически загружаемых модулей расширения, которые должны быть работоспособны в Windows (как минимум), компилятор сообщает, что это недопустимый инициализатор. Поэтому принято передавать *NULL* макросу `PyObject_HEAD_INIT` и инициализировать это поле явно в начале функции инициализации модуля, прежде чем делать что-либо ещё. Обычно это делается так:118119```c120Foo_Type.ob_type = &PyType_Type;121```122123Это должно быть сделано до создания любых экземпляров типа. [`PyType_Ready()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Ready) проверяет, является ли `ob_type` значением *NULL*, и если это так, инициализирует его полем `ob_type` базового класса. [`PyType_Ready()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Ready) не изменит это поле, если оно не равно нулю.124125Это поле наследуется подтипами.126127**Py\_ssize\_t `PyVarObject.ob_size`**128129Для статически выделенных объектов-типов это поле должно быть инициализировано нулём. Для динамически выделенных объектов-типов это поле имеет особый внутренний смысл.130131Это поле не наследуется подтипами.132133**const char\* `PyTypeObject.tp_name`**134135Указатель на строку, завершающуюся NUL, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка и имя типа; для встроенных типов – только имя типа. Если модуль является подмодулем пакета, полное имя пакета входит в полное имя модуля. Например, тип с именем `T`, определённый в модуле `M` в подпакете `Q` пакета `P`, должен иметь инициализатор [`tp_name`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_name) `"P.Q.M.T"`.136137Для динамически выделенных объектов типов это должно быть просто имя типа, а имя модуля должно явно храниться в словаре типа как значение ключа `'__module__'`.138139Для статически выделенных объектов типов поле tp\_name должно содержать точку. Всё, что до последней точки, становится доступным как атрибут `__module__`, а всё, что после последней точки, – как атрибут [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__).140141Если точка отсутствует, всё поле [`tp_name`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_name) становится доступным как атрибут [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__), а атрибут `__module__` не определён (если только он не задан явно в словаре, как объяснялось выше). Это означает, что тип будет невозможно сериализовать с помощью pickle.142143Это поле не наследуется подтипами.144145**Py\_ssize\_t `PyTypeObject.tp_basicsize`**146147**Py\_ssize\_t `PyTypeObject.tp_itemsize`**148149Эти поля позволяют вычислить размер экземпляров типа в байтах.150151Существует два вида типов: типы с экземплярами фиксированной длины имеют нулевое поле [`tp_itemsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), а типы с экземплярами переменной длины – ненулевое поле [`tp_itemsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_itemsize). Для типа с экземплярами фиксированной длины все экземпляры имеют одинаковый размер, задаваемый в [`tp_basicsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).152153Для типа с экземплярами переменной длины экземпляры должны иметь поле `ob_size`, а размер экземпляра равен [`tp_basicsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) плюс N умноженное на [`tp_itemsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), где N – это «длина» объекта. Значение N обычно хранится в поле `ob_size` экземпляра. Бывают исключения: например, int использует отрицательное `ob_size` для обозначения отрицательного числа, и N там равно `abs(ob_size)`. Кроме того, наличие поля `ob_size` в структуре экземпляра не означает, что структура экземпляра имеет переменную длину (например, структура для типа списка имеет экземпляры фиксированной длины, но эти экземпляры имеют значимое поле `ob_size`).154155Базовый размер включает поля в экземпляре, объявленные макросом [`PyObject_HEAD`](https://python-all.ru/3.4/c-api/structures.html#c.PyObject_HEAD) или [`PyObject_VAR_HEAD`](https://python-all.ru/3.4/c-api/structures.html#c.PyObject_VAR_HEAD) (в зависимости от того, какой из них используется для объявления структуры экземпляра), и это, в свою очередь, включает поля `_ob_prev` и `_ob_next`, если они присутствуют. Это означает, что единственный правильный способ получить инициализатор для [`tp_basicsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) – использовать оператор `sizeof` для структуры, используемой для объявления размещения экземпляра. Базовый размер не включает размер заголовка GC.156157Эти поля наследуются подтипами отдельно. Если базовый тип имеет ненулевое [`tp_itemsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), то, как правило, небезопасно устанавливать [`tp_itemsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) в другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).158159Замечание о выравнивании: если элементы переменной длины требуют определённого выравнивания, это должно обеспечиваться значением [`tp_basicsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_basicsize). Пример: предположим, тип реализует массив из `double`. [`tp_itemsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) равно `sizeof(double)`. Ответственность программиста – сделать так, чтобы [`tp_basicsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) было кратно `sizeof(double)` (предполагая, что это требование выравнивания для `double`).160161**destructor `PyTypeObject.tp_dealloc`**162163Указатель на функцию-деструктор экземпляра. Эта функция должна быть определена, если только тип не гарантирует, что его экземпляры никогда не будут освобождены (как в случае с синглтонами `None` и `Ellipsis`).164165Функция-деструктор вызывается макросами [`Py_DECREF()`](https://python-all.ru/3.4/c-api/refcounting.html#c.Py_DECREF) и [`Py_XDECREF()`](https://python-all.ru/3.4/c-api/refcounting.html#c.Py_XDECREF), когда счётчик ссылок становится нулевым. В этот момент экземпляр всё ещё существует, но на него нет ссылок. Функция-деструктор должна освободить все ссылки, которыми владеет экземпляр, освободить все буферы памяти, принадлежащие экземпляру (с помощью функции освобождения, соответствующей функции выделения, использованной для выделения буфера), и наконец (последним действием) вызвать функцию [`tp_free`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_free) типа. Если тип не является субтипируемым (не имеет установленного флага [`Py_TPFLAGS_BASETYPE`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_BASETYPE)), можно вызвать освободитель объекта напрямую, а не через [`tp_free`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_free). Освободитель объекта должен быть тем же, который использовался для выделения экземпляра; обычно это [`PyObject_Del()`](https://python-all.ru/3.4/c-api/allocation.html#c.PyObject_Del), если экземпляр был выделен с помощью [`PyObject_New()`](https://python-all.ru/3.4/c-api/allocation.html#c.PyObject_New) или `PyObject_VarNew()`, или [`PyObject_GC_Del()`](https://python-all.ru/3.4/c-api/gcsupport.html#c.PyObject_GC_Del), если экземпляр был выделен с помощью [`PyObject_GC_New()`](https://python-all.ru/3.4/c-api/gcsupport.html#c.PyObject_GC_New) или [`PyObject_GC_NewVar()`](https://python-all.ru/3.4/c-api/gcsupport.html#c.PyObject_GC_NewVar).166167Это поле наследуется подтипами.168169**printfunc `PyTypeObject.tp_print`**170171Зарезервированный слот, ранее использовавшийся для форматирования вывода в Python 2.x.172173**getattrfunc `PyTypeObject.tp_getattr`**174175Необязательный указатель на функцию получения строки атрибута.176177Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция [`tp_getattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattro), но принимает C-строку вместо строкового объекта Python для указания имени атрибута. Сигнатура такая же, как у [`PyObject_GetAttrString()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_GetAttrString).178179Это поле наследуется подтипами вместе с [`tp_getattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattro): подтип наследует и [`tp_getattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattr), и [`tp_getattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattr) и [`tp_getattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattro) подтипа оба равны *NULL*.180181**setattrfunc `PyTypeObject.tp_setattr`**182183Необязательный указатель на функцию установки строкового атрибута.184185Это поле устарело. Если оно определено, оно должно указывать на функцию, которая ведет себя так же, как [`tp_setattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattro), но принимает строку C вместо строкового объекта Python для указания имени атрибута. Сигнатура такая же, как у [`PyObject_SetAttrString()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_SetAttrString).186187Это поле наследуется подтипами вместе с [`tp_setattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattro): подтип наследует как [`tp_setattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattr), так и [`tp_setattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattro) от своего базового типа, когда [`tp_setattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattr) и [`tp_setattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattro) подтипа равны *NULL*.188189**void\* `PyTypeObject.tp_reserved`**190191Зарезервированный слот, ранее известный как tp\_compare.192193**reprfunc `PyTypeObject.tp_repr`**194195Необязательный указатель на функцию, реализующую встроенную функцию [`repr()`](https://python-all.ru/3.4/library/functions.html#repr).196197Сигнатура такая же, как у [`PyObject_Repr()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Repr); она должна возвращать строку или объект Unicode. В идеале эта функция должна возвращать строку, которая при передаче в [`eval()`](https://python-all.ru/3.4/library/functions.html#eval) в подходящем окружении возвращает объект с тем же значением. Если это невозможно, она должна возвращать строку, начинающуюся с `'<'` и заканчивающуюся `'>'`, по которой можно определить как тип, так и значение объекта.198199Если это поле не задано, возвращается строка вида `<%s object at %p>`, где `%s` заменяется на имя типа, а `%p` – на адрес памяти объекта.200201Это поле наследуется подтипами.202203**[PyNumberMethods](https://python-all.ru/3.4/c-api/typeobj.html#c.PyNumberMethods)\* `tp_as_number`**204205Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих числовой протокол. Эти поля описаны в [*Структуры числовых объектов*](https://python-all.ru/3.4/c-api/typeobj.html#number-structs).206207Поле `tp_as_number` не наследуется, но содержащиеся в нем поля наследуются по отдельности.208209**[PySequenceMethods](https://python-all.ru/3.4/c-api/typeobj.html#c.PySequenceMethods)\* `tp_as_sequence`**210211Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол последовательности. Эти поля описаны в [*Структуры объектов-последовательностей*](https://python-all.ru/3.4/c-api/typeobj.html#sequence-structs).212213Поле `tp_as_sequence` не наследуется, но содержащиеся в нем поля наследуются по отдельности.214215**[PyMappingMethods](https://python-all.ru/3.4/c-api/typeobj.html#c.PyMappingMethods)\* `tp_as_mapping`**216217Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол отображения. Эти поля описаны в [*Структуры объектов-отображений*](https://python-all.ru/3.4/c-api/typeobj.html#mapping-structs).218219Поле `tp_as_mapping` не наследуется, но содержащиеся в нем поля наследуются по отдельности.220221**hashfunc `PyTypeObject.tp_hash`**222223Необязательный указатель на функцию, реализующую встроенную функцию [`hash()`](https://python-all.ru/3.4/library/functions.html#hash).224225Сигнатура такая же, как у [`PyObject_Hash()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Hash); она должна возвращать значение типа Py\_hash\_t. Значение `-1` не должно возвращаться как обычное возвращаемое значение; при возникновении ошибки во время вычисления хеша функция должна установить исключение и вернуть `-1`.226227Это поле может быть явно установлено в [`PyObject_HashNotImplemented()`](https://python-all.ru/3.4/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.4/c-api/object.html#c.PyObject_HashNotImplemented).228229Если это поле не установлено, попытка получить хеш объекта вызывает [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError).230231Это поле наследуется подтипами вместе с [`tp_richcompare`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_richcompare): подтип наследует как [`tp_richcompare`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_richcompare), так и [`tp_hash`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_hash), когда [`tp_richcompare`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа равны *NULL*.232233**ternaryfunc `PyTypeObject.tp_call`**234235Необязательный указатель на функцию, реализующую вызов объекта. Он должен быть *NULL*, если объект не является вызываемым. Сигнатура такая же, как у [`PyObject_Call()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Call).236237Это поле наследуется подтипами.238239**reprfunc `PyTypeObject.tp_str`**240241Необязательный указатель на функцию, реализующую встроенную операцию [`str()`](https://python-all.ru/3.4/library/stdtypes.html#str). (Обратите внимание, что [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) теперь является типом, и [`str()`](https://python-all.ru/3.4/library/stdtypes.html#str) вызывает конструктор этого типа. Этот конструктор вызывает [`PyObject_Str()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Str) для выполнения фактической работы, а [`PyObject_Str()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Str) вызовет этот обработчик.)242243Сигнатура такая же, как у [`PyObject_Str()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Str); она должна возвращать строку или объект Unicode. Эта функция должна возвращать «дружественное» строковое представление объекта, так как это представление будет использоваться, в частности, функцией [`print()`](https://python-all.ru/3.4/library/functions.html#print).244245Если это поле не установлено, вызывается [`PyObject_Repr()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Repr) для возврата строкового представления.246247Это поле наследуется подтипами.248249**getattrofunc `PyTypeObject.tp_getattro`**250251Необязательный указатель на функцию получения атрибута.252253Сигнатура такая же, как у [`PyObject_GetAttr()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_GetAttr). Обычно удобно устанавливать это поле в [`PyObject_GenericGetAttr()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_GenericGetAttr), который реализует обычный способ поиска атрибутов объекта.254255Это поле наследуется подтипами вместе с [`tp_getattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattr): подтип наследует как [`tp_getattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattr), так и [`tp_getattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattr) и [`tp_getattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_getattro) подтипа равны *NULL*.256257**setattrofunc `PyTypeObject.tp_setattro`**258259Необязательный указатель на функцию установки атрибута.260261Сигнатура такая же, как у [`PyObject_SetAttr()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_SetAttr). Обычно удобно устанавливать это поле в [`PyObject_GenericSetAttr()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_GenericSetAttr), которая реализует обычный способ установки атрибутов объекта.262263Это поле наследуется подтипами вместе с [`tp_setattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattr): подтип наследует как [`tp_setattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattr), так и [`tp_setattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattro) от базового типа, когда собственные поля [`tp_setattr`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattr) и [`tp_setattro`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_setattro) подтипа оба равны *NULL*.264265**[PyBufferProcs](https://python-all.ru/3.4/c-api/typeobj.html#c.PyBufferProcs)\* `PyTypeObject.tp_as_buffer`**266267Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих буферный интерфейс. Эти поля описаны в [*Buffer Object Structures*](https://python-all.ru/3.4/c-api/typeobj.html#buffer-structs).268269Поле [`tp_as_buffer`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer) не наследуется, но содержащиеся в нём поля наследуются по отдельности.270271**unsigned long `PyTypeObject.tp_flags`**272273Это поле представляет собой битовую маску различных флагов. Некоторые флаги указывают на варианты семантики для определённых ситуаций; другие используются, чтобы показать, что определённые поля в объекте типа (или в структурах расширения, доступных через `tp_as_number`, `tp_as_sequence`, `tp_as_mapping`, и [`tp_as_buffer`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer)), которые исторически не всегда присутствовали, действительны; если такой бит флага сброшен, поля типа, которые он охраняет, не должны быть доступны и должны считаться имеющими нулевое значение или *NULL*.274275Наследование этого поля сложное. Большинство битов флагов наследуются по отдельности, т.е. если у базового типа установлен бит флага, подтип наследует этот бит флага. Биты флагов, относящиеся к структурам расширения, строго наследуются, если наследуется сама структура расширения – значение бита флага базового типа копируется в подтип вместе с указателем на структуру расширения. Бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) наследуется вместе с полями [`tp_traverse`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear), т.е. если [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) сброшен в подтипе, а [`tp_traverse`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) в подтипе существуют и имеют *NULL*.276277В настоящее время определены следующие битовые маски; их можно объединить с помощью оператора `|`, чтобы сформировать значение поля [`tp_flags`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_flags). Макрос [`PyType_HasFeature()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_HasFeature) принимает тип и значение флагов, *tp* и *f*, и проверяет, является ли `tp->tp_flags & f` ненулевым.278279#### `Py_TPFLAGS_HEAPTYPE`280281Этот бит устанавливается, когда сам объект типа выделяется в куче. В этом случае поле `ob_type` его экземпляров считается ссылкой на тип, и объект типа инкрементируется (INCREF), когда создаётся новый экземпляр, и декрементируется (DECREF), когда экземпляр уничтожается (это не относится к экземплярам подтипов; только тип, на который ссылается ob\_type экземпляра, инкрементируется или декрементируется).282283#### `Py_TPFLAGS_BASETYPE`284285Этот бит устанавливается, когда тип может использоваться как базовый тип другого типа. Если этот бит сброшен, тип не может быть унаследован (аналогично «финальному» классу в Java).286287#### `Py_TPFLAGS_READY`288289Этот бит устанавливается, когда объект типа был полностью инициализирован с помощью [`PyType_Ready()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Ready).290291#### `Py_TPFLAGS_READYING`292293Этот бит устанавливается, пока [`PyType_Ready()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Ready) находится в процессе инициализации объекта типа.294295#### `Py_TPFLAGS_HAVE_GC`296297Этот бит устанавливается, когда объект поддерживает сборку мусора. Если этот бит установлен, экземпляры должны создаваться с помощью [`PyObject_GC_New()`](https://python-all.ru/3.4/c-api/gcsupport.html#c.PyObject_GC_New) и уничтожаться с помощью [`PyObject_GC_Del()`](https://python-all.ru/3.4/c-api/gcsupport.html#c.PyObject_GC_Del). Дополнительная информация в разделе [*Поддержка циклической сборки мусора*](https://python-all.ru/3.4/c-api/gcsupport.html#supporting-cycle-detection). Этот бит также означает, что связанные со сборкой мусора поля [`tp_traverse`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) присутствуют в объекте типа.298299#### `Py_TPFLAGS_DEFAULT`300301Это битовая маска всех битов, относящихся к существованию определённых полей в объекте типа и его структурах расширения. В настоящее время она включает следующие биты: `Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`, `Py_TPFLAGS_HAVE_VERSION_TAG`.302303#### `Py_TPFLAGS_LONG_SUBCLASS`304305#### `Py_TPFLAGS_LIST_SUBCLASS`306307#### `Py_TPFLAGS_TUPLE_SUBCLASS`308309#### `Py_TPFLAGS_BYTES_SUBCLASS`310311#### `Py_TPFLAGS_UNICODE_SUBCLASS`312313#### `Py_TPFLAGS_DICT_SUBCLASS`314315#### `Py_TPFLAGS_BASE_EXC_SUBCLASS`316317#### `Py_TPFLAGS_TYPE_SUBCLASS`318319Эти флаги используются такими функциями, как [`PyLong_Check()`](https://python-all.ru/3.4/c-api/long.html#c.PyLong_Check), чтобы быстро определить, является ли тип подклассом встроенного типа; такие конкретные проверки выполняются быстрее, чем общая проверка, например [`PyObject_IsInstance()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_IsInstance). Пользовательские типы, наследующие от встроенных, должны иметь соответствующим образом установленные поля [`tp_flags`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_flags), иначе код, взаимодействующий с такими типами, будет вести себя по-разному в зависимости от того, какая проверка используется.320321#### `Py_TPFLAGS_HAVE_FINALIZE`322323Этот бит устанавливается, когда слот [`tp_finalize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_finalize) присутствует в структуре типа.324325Новое в версии 3.4.326327**const char\* `PyTypeObject.tp_doc`**328329Необязательный указатель на C-строку, завершающуюся NUL, содержащую строку документации для этого объекта типа. Он доступен как атрибут `__doc__` у типа и его экземпляров.330331Это поле *не* наследуется подтипами.332333**[traverseproc](https://python-all.ru/3.4/c-api/gcsupport.html#c.traverseproc) `PyTypeObject.tp_traverse`**334335Необязательный указатель на функцию обхода для сборщика мусора. Используется только если установлен бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Дополнительную информацию о схеме сборки мусора в Python можно найти в разделе [*Supporting Cyclic Garbage Collection*](https://python-all.ru/3.4/c-api/gcsupport.html#supporting-cycle-detection).336337Указатель [`tp_traverse`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_traverse) используется сборщиком мусора для обнаружения циклических ссылок. Типичная реализация функции [`tp_traverse`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_traverse) просто вызывает [`Py_VISIT()`](https://python-all.ru/3.4/c-api/gcsupport.html#c.Py_VISIT) для каждого члена экземпляра, являющегося объектом Python. Например, это функция `local_traverse()` из модуля расширения [`_thread`](https://python-all.ru/3.4/library/_thread.html#module-_thread):338339```c340static int341local_traverse(localobject *self, visitproc visit, void *arg)342{343    Py_VISIT(self->args);344    Py_VISIT(self->kw);345    Py_VISIT(self->dict);346    return 0;347}348```349350Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/3.4/c-api/gcsupport.html#c.Py_VISIT) вызывается только для тех членов, которые могут участвовать в циклических ссылках. Хотя есть также член `self->key`, он может быть только *NULL* или строкой Python и поэтому не может быть частью циклической ссылки.351352С другой стороны, даже если известно, что член никогда не может быть частью цикла, в качестве средства отладки его можно всё равно посетить, чтобы функция [`get_referents()`](https://python-all.ru/3.4/library/gc.html#gc.get_referents) модуля [`gc`](https://python-all.ru/3.4/library/gc.html#module-gc) включала его.353354Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/3.4/c-api/gcsupport.html#c.Py_VISIT) требует, чтобы параметры *visit* и *arg* функции `local_traverse()` имели именно такие имена; не называйте их как угодно.355356Это поле наследуется подтипами вместе с [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) и битом флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): бит флага, [`tp_traverse`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) наследуются от базового типа, если все они равны нулю в подтипе.357358**[inquiry](https://python-all.ru/3.4/c-api/gcsupport.html#c.inquiry) `PyTypeObject.tp_clear`**359360Необязательный указатель на функцию очистки для сборщика мусора. Используется только если установлен бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).361362Функция-член [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) используется для разрыва циклических ссылок в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности все функции [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) в системе должны вместе разрывать все циклические ссылки. Это тонкий момент, и если есть сомнения, стоит предоставить функцию [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear). Например, тип tuple не реализует функцию [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear), поскольку можно доказать, что никакая циклическая ссылка не может состоять только из кортежей. Поэтому функции [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) других типов должны быть достаточны для разрыва любой циклической ссылки, содержащей кортеж. Это не сразу очевидно, и редко есть веская причина избегать реализации [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear).363364Реализации [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) должны обнулять ссылки экземпляра на те его члены, которые могут быть объектами Python, и устанавливать указатели на эти члены в *NULL*, как в следующем примере:365366```c367static int368local_clear(localobject *self)369{370    Py_CLEAR(self->key);371    Py_CLEAR(self->args);372    Py_CLEAR(self->kw);373    Py_CLEAR(self->dict);374    return 0;375}376```377378Следует использовать макрос [`Py_CLEAR()`](https://python-all.ru/3.4/c-api/refcounting.html#c.Py_CLEAR), поскольку очистка ссылок – деликатная операция: ссылка на содержащийся объект не должна уменьшаться до тех пор, пока указатель на содержащийся объект не будет установлен в *NULL*. Это связано с тем, что уменьшение счётчика ссылок может привести к тому, что содержащийся объект станет мусором, что вызовет цепочку действий по его освобождению, которая может включать вызов произвольного кода Python (из-за финализаторов или колбэков слабых ссылок, связанных с содержащимся объектом). Если такой код может снова обратиться к *self*, важно, чтобы указатель на содержащийся объект в этот момент был *NULL*, чтобы *self* знал, что содержащийся объект больше не может использоваться. Макрос [`Py_CLEAR()`](https://python-all.ru/3.4/c-api/refcounting.html#c.Py_CLEAR) выполняет операции в безопасном порядке.379380Поскольку цель функций [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) – разрывать циклические ссылки, нет необходимости очищать содержащиеся объекты, такие как строки или целые числа Python, которые не могут участвовать в циклических ссылках. С другой стороны, может быть удобно очищать все содержащиеся объекты Python и реализовать функцию [`tp_dealloc`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dealloc) типа так, чтобы она вызывала [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear).381382Дополнительную информацию о схеме сборки мусора Python можно найти в разделе [*Поддержка циклической сборки мусора*](https://python-all.ru/3.4/c-api/gcsupport.html#supporting-cycle-detection).383384Это поле наследуется подтипами вместе с [`tp_traverse`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и битом флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): бит флага, [`tp_traverse`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_clear) наследуются от базового типа, если все они равны нулю в подтипе.385386**richcmpfunc `PyTypeObject.tp_richcompare`**387388Необязательный указатель на функцию расширенного сравнения, сигнатура которой: `PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)`. Первый параметр гарантированно является экземпляром типа, определённого [`PyTypeObject`](https://python-all.ru/3.4/c-api/type.html#c.PyTypeObject).389390Функция должна возвращать результат сравнения (обычно `Py_True` или `Py_False`). Если сравнение не определено, она должна вернуть `Py_NotImplemented`; если произошла другая ошибка – вернуть `NULL` и установить условие исключения.391392> **Примечание**393>394> Если требуется реализовать тип, для которого имеет смысл только ограниченный набор сравнений (например, `==` и `!=`, но не `<` и подобные), следует напрямую возбуждать [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError) в функции расширенного сравнения.395396Это поле наследуется подтипами вместе с [`tp_hash`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_hash): подтип наследует [`tp_richcompare`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_hash), когда оба поля [`tp_richcompare`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа равны *NULL*.397398Следующие константы определены для использования в качестве третьего аргумента для [`tp_richcompare`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и для [`PyObject_RichCompare()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_RichCompare):399400| Константа | Сравнение |401| --- | --- |402| `Py_LT` | `<` |403| `Py_LE` | `<=` |404| `Py_EQ` | `==` |405| `Py_NE` | `!=` |406| `Py_GT` | `>` |407| `Py_GE` | `>=` |408409**Py\_ssize\_t `PyTypeObject.tp_weaklistoffset`**410411Если экземпляры этого типа поддерживают слабые ссылки, это поле больше нуля и содержит смещение в структуре экземпляра до головы списка слабых ссылок (игнорируя заголовок GC, если он присутствует); это смещение используется функциями `PyObject_ClearWeakRefs()` и `PyWeakref_*()`. Структура экземпляра должна содержать поле типа [`PyObject*`](https://python-all.ru/3.4/c-api/structures.html#c.PyObject), которое инициализируется значением *NULL*.412413Не путайте это поле с [`tp_weaklist`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_weaklist); это голова списка для слабых ссылок на сам объект типа.414415Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что подтип использует другую голову списка слабых ссылок, чем базовый тип. Поскольку голова списка всегда находится через [`tp_weaklistoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset), это не должно быть проблемой.416417Когда тип, определённый с помощью class, не имеет объявления [`__slots__`](https://python-all.ru/3.4/reference/datamodel.html#object.__slots__), и ни один из его базовых типов не поддерживает слабые ссылки, тип становится поддерживающим слабые ссылки путём добавления слота головы списка слабых ссылок в структуру экземпляра и установки [`tp_weaklistoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) в смещение этого слота.418419Когда объявление `__slots__` типа содержит слот с именем `__weakref__`, этот слот становится головой списка слабых ссылок для экземпляров типа, а его смещение сохраняется в поле типа [`tp_weaklistoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset).420421Если объявление `__slots__` типа не содержит слота с именем `__weakref__`, тип наследует своё значение [`tp_weaklistoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) от базового типа.422423**getiterfunc `PyTypeObject.tp_iter`**424425Необязательный указатель на функцию, возвращающую итератор для объекта. Его наличие обычно указывает на то, что экземпляры этого типа являются итерируемыми (хотя последовательности могут быть итерируемыми и без этой функции).426427Эта функция имеет ту же сигнатуру, что и [`PyObject_GetIter()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_GetIter).428429Это поле наследуется подтипами.430431**iternextfunc `PyTypeObject.tp_iternext`**432433Необязательный указатель на функцию, возвращающую следующий элемент итератора. Когда итератор исчерпан, она должна вернуть *NULL*; исключение [`StopIteration`](https://python-all.ru/3.4/library/exceptions.html#StopIteration) может быть установлено, а может и нет. При возникновении другой ошибки она также должна вернуть *NULL*. Наличие этой функции указывает, что экземпляры данного типа являются итераторами.434435Типы-итераторы также должны определять функцию [`tp_iter`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_iter), и эта функция должна возвращать сам экземпляр итератора (не новый экземпляр итератора).436437Эта функция имеет ту же сигнатуру, что и [`PyIter_Next()`](https://python-all.ru/3.4/c-api/iter.html#c.PyIter_Next).438439Это поле наследуется подтипами.440441**struct [PyMethodDef](https://python-all.ru/3.4/c-api/structures.html#c.PyMethodDef)\* `PyTypeObject.tp_methods`**442443Необязательный указатель на статический массив структур [`PyMethodDef`](https://python-all.ru/3.4/c-api/structures.html#c.PyMethodDef), завершающийся *NULL*, объявляющий обычные методы этого типа.444445Для каждой записи массива в словарь типа (см. [`tp_dict`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже) добавляется запись, содержащая дескриптор метода.446447Это поле не наследуется подтипами (методы наследуются через другой механизм).448449**struct [PyMemberDef](https://python-all.ru/3.4/c-api/structures.html#c.PyMemberDef)\* `PyTypeObject.tp_members`**450451Необязательный указатель на статический массив структур [`PyMemberDef`](https://python-all.ru/3.4/c-api/structures.html#c.PyMemberDef), завершающийся *NULL*, объявляющий обычные элементы данных (поля или слоты) экземпляров этого типа.452453Для каждой записи массива в словарь типа (см. [`tp_dict`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже) добавляется запись, содержащая дескриптор элемента.454455Это поле не наследуется подтипами (члены наследуются через другой механизм).456457**struct PyGetSetDef\* `PyTypeObject.tp_getset`**458459Необязательный указатель на статический массив структур `PyGetSetDef`, завершающийся *NULL*, объявляющий вычисляемые атрибуты экземпляров этого типа.460461Для каждой записи массива в словарь типа (см. [`tp_dict`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже) добавляется запись, содержащая дескриптор getset.462463Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).464465Документация для PyGetSetDef:466467```c468typedef PyObject *(*getter)(PyObject *, void *);469typedef int (*setter)(PyObject *, PyObject *, void *);470471typedef struct PyGetSetDef {472    char *name;    /* имя атрибута */473    getter get;    /* C-функция для получения атрибута */474    setter set;    /* C-функция для установки атрибута */475    char *doc;     /* необязательная строка документации */476    void *closure; /* необязательные дополнительные данные для геттера и сеттера */477} PyGetSetDef;478```479480**[PyTypeObject](https://python-all.ru/3.4/c-api/type.html#c.PyTypeObject)\* `PyTypeObject.tp_base`**481482Необязательный указатель на базовый тип, от которого наследуются свойства типа. На этом уровне поддерживается только одиночное наследование; множественное наследование требует динамического создания объекта типа вызовом метатипа.483484Это поле не наследуется подтипами (очевидно), но по умолчанию оно равно `&PyBaseObject_Type` (которое программистам Python известно как тип [`object`](https://python-all.ru/3.4/library/functions.html#object)).485486**[PyObject](https://python-all.ru/3.4/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_dict`**487488Словарь типа сохраняется здесь функцией [`PyType_Ready()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Ready).489490Обычно это поле должно быть инициализировано значением *NULL* перед вызовом PyType\_Ready; его также можно инициализировать словарём, содержащим начальные атрибуты типа. После того как [`PyType_Ready()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Ready) инициализирует тип, в этот словарь можно добавлять дополнительные атрибуты только если они не соответствуют перегруженным операциям (например, [`__add__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__add__)).491492Это поле не наследуется подтипами (хотя определённые здесь атрибуты наследуются через другой механизм).493494> **Предупреждение**495>496> Небезопасно использовать [`PyDict_SetItem()`](https://python-all.ru/3.4/c-api/dict.html#c.PyDict_SetItem) или иным образом изменять [`tp_dict`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dict) с помощью C-API словарей.497498**descrgetfunc `PyTypeObject.tp_descr_get`**499500Необязательный указатель на функцию «descriptor get».501502Сигнатура функции:503504```c505PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);506```507508Это поле наследуется подтипами.509510**descrsetfunc `PyTypeObject.tp_descr_set`**511512Необязательный указатель на функцию «установки дескриптора».513514Сигнатура функции:515516```c517int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);518```519520Это поле наследуется подтипами.521522**Py\_ssize\_t `PyTypeObject.tp_dictoffset`**523524Если экземпляры этого типа имеют словарь, содержащий переменные экземпляра, это поле не равно нулю и содержит смещение словаря переменных экземпляра в структуре экземпляров типа; это смещение используется функцией [`PyObject_GenericGetAttr()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_GenericGetAttr).525526Не путайте это поле с [`tp_dict`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dict); это словарь для атрибутов самого объекта типа.527528Если значение этого поля больше нуля, оно задаёт смещение от начала структуры экземпляра. Если значение меньше нуля, оно задаёт смещение от *конца* структуры экземпляра. Отрицательное смещение использовать дороже, и его следует применять только если структура экземпляра содержит часть переменной длины. Это используется, например, для добавления словаря переменных экземпляра к подтипам [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) или [`tuple`](https://python-all.ru/3.4/library/stdtypes.html#tuple). Обратите внимание, что поле [`tp_basicsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) должно учитывать словарь, добавленный в конец, даже если сам словарь не входит в базовую компоновку объекта. В системе с размером указателя 4 байта [`tp_dictoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) должно быть установлено в `-4`, чтобы указать, что словарь находится в самом конце структуры.529530Реальное смещение словаря в экземпляре можно вычислить из отрицательного [`tp_dictoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) следующим образом:531532```c533dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset534if dictoffset is not aligned on sizeof(void*):535    round up to sizeof(void*)536```537538где [`tp_basicsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_basicsize), [`tp_itemsize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) и [`tp_dictoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) берутся из объекта типа, а `ob_size` берётся из экземпляра. Используется абсолютное значение, потому что целые числа используют знак `ob_size` для хранения знака числа. (Никогда не нужно выполнять это вычисление самостоятельно; это делается за вас функцией `_PyObject_GetDictPtr()`.)539540Это поле наследуется подтипами, но обратитесь к списку правил ниже. Подтип может переопределить это смещение; это означает, что экземпляры подтипа хранят словарь по другому смещению, нежели базовый тип. Поскольку словарь всегда находится через [`tp_dictoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset), это не должно вызывать проблем.541542Когда тип, определённый с помощью оператора class, не содержит объявления [`__slots__`](https://python-all.ru/3.4/reference/datamodel.html#object.__slots__) и ни один из его базовых типов не имеет словаря переменных экземпляра, в макет экземпляра добавляется слот для словаря, а [`tp_dictoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) устанавливается в смещение этого слота.543544Если тип, определённый с помощью оператора class, содержит объявление `__slots__`, такой тип наследует свой [`tp_dictoffset`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) от базового типа.545546(Добавление слота с именем [`__dict__`](https://python-all.ru/3.4/library/stdtypes.html#object.__dict__) в объявление `__slots__` не даёт ожидаемого эффекта, а лишь вносит путаницу. Возможно, эту возможность стоило бы добавить как отдельную фичу, наподобие `__weakref__`, хотя.)547548**initproc `PyTypeObject.tp_init`**549550Необязательный указатель на функцию инициализации экземпляра.551552Эта функция соответствует методу классов [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__). Как и для [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__), можно создать экземпляр, не вызывая [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__), а также можно переинициализировать экземпляр, повторно вызвав его метод [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__).553554Сигнатура функции:555556```c557int tp_init(PyObject *self, PyObject *args, PyObject *kwds)558```559560Аргумент self – это инициализируемый экземпляр; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова [`__init__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__init__).561562Функция [`tp_init`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_init), если она не *NULL*, вызывается при обычном создании экземпляра вызовом его типа, после того как функция [`tp_new`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_new) этого типа вернёт экземпляр данного типа. Если функция [`tp_new`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_new) возвращает экземпляр некоторого другого типа, не являющегося подтипом исходного, то функция [`tp_init`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_init) не вызывается; если же [`tp_new`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_new) возвращает экземпляр подтипа исходного типа, то вызывается [`tp_init`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_init) этого подтипа.563564Это поле наследуется подтипами.565566**allocfunc `PyTypeObject.tp_alloc`**567568Необязательный указатель на функцию выделения экземпляра.569570Сигнатура функции:571572```c573PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)574```575576Назначение этой функции – разделить выделение памяти и её инициализацию. Она должна возвращать указатель на блок памяти достаточного для экземпляра размера, подходящим образом выровненный и заполненный нулями, но с полем `ob_refcnt`, установленным в `1`, и полем `ob_type`, установленным в аргумент типа. Если [`tp_itemsize`](https://python-all.ru/3.4/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.4/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).577578Не используйте эту функцию для какой-либо другой инициализации экземпляра, даже для выделения дополнительной памяти; это должно делаться с помощью [`tp_new`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_new).579580Это поле наследуется статическими подтипами, но не динамическими (подтипами, созданными с помощью оператора class); у последних это поле всегда устанавливается в [`PyType_GenericAlloc()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_GenericAlloc), чтобы принудительно применить стандартную стратегию выделения памяти в куче. Это же значение рекомендуется и для статически определённых типов.581582**newfunc `PyTypeObject.tp_new`**583584Необязательный указатель на функцию создания экземпляра.585586Если для данного типа эта функция равна *NULL*, то этот тип нельзя вызвать для создания новых экземпляров; предполагается, что существует другой способ создания экземпляров, например, фабричная функция.587588Сигнатура функции:589590```c591PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)592```593594Аргумент subtype – это тип создаваемого объекта; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова типа. Обратите внимание, что subtype не обязан совпадать с типом, чья функция [`tp_new`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_new) вызывается; это может быть подтип этого типа (но не какой-то другой, не связанный тип).595596Функция [`tp_new`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_new) должна вызывать `subtype->tp_alloc(subtype, nitems)` для выделения памяти под объект, а затем выполнять лишь ту дополнительную инициализацию, которая абсолютно необходима. Инициализация, которую можно безопасно пропустить или повторить, должна быть помещена в обработчик [`tp_init`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_init). Хорошее эмпирическое правило: для неизменяемых типов вся инициализация должна происходить в [`tp_new`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_new), а для изменяемых типов большую часть инициализации следует откладывать до [`tp_init`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_init).597598Это поле наследуется подтипами, за исключением статических типов, у которых [`tp_base`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_base) равно *NULL* или `&PyBaseObject_Type`.599600**destructor `PyTypeObject.tp_free`**601602Необязательный указатель на функцию освобождения экземпляра. Её сигнатура – `freefunc`:603604```c605void tp_free(void *)606```607608Инициализатор, совместимый с этой сигнатурой – `PyObject_Free()`.609610Это поле наследуется статическими подтипами, но не динамическими (подтипами, созданными с помощью оператора class); у последних это поле устанавливается в деаллокатор, подходящий для [`PyType_GenericAlloc()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_GenericAlloc) и значения флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).611612**[inquiry](https://python-all.ru/3.4/c-api/gcsupport.html#c.inquiry) `PyTypeObject.tp_is_gc`**613614Необязательный указатель на функцию, вызываемую сборщиком мусора.615616Сборщику мусора необходимо знать, подлежит ли конкретный объект сборке или нет. Обычно достаточно посмотреть на поле [`tp_flags`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_flags) типа объекта и проверить флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Но у некоторых типов имеется смесь статически и динамически выделенных экземпляров, и статически выделенные экземпляры не подлежат сборке. Таким типам следует определить эту функцию; она должна возвращать `1` для подлежащего сборке экземпляра и `0` – для неподлежащего. Сигнатура:617618```c619int tp_is_gc(PyObject *self)620```621622(Единственный пример этого – сами типы. Метатип [`PyType_Type`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Type) определяет эту функцию, чтобы различать статически и динамически выделенные типы.)623624Это поле наследуется подтипами.625626**[PyObject](https://python-all.ru/3.4/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_bases`**627628Кортеж базовых типов.629630Это устанавливается для типов, созданных с помощью оператора class. Для статически определённых типов оно должно быть равно *NULL*.631632Это поле не наследуется.633634**[PyObject](https://python-all.ru/3.4/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_mro`**635636Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая [`object`](https://python-all.ru/3.4/library/functions.html#object), в порядке разрешения методов (MRO).637638Это поле не наследуется; оно вычисляется заново функцией [`PyType_Ready()`](https://python-all.ru/3.4/c-api/type.html#c.PyType_Ready).639640**destructor `PyTypeObject.tp_finalize`**641642Необязательный указатель на функцию финализации экземпляра. Её сигнатура – `destructor`:643644```c645void tp_finalize(PyObject *)646```647648Если [`tp_finalize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_finalize) установлен, интерпретатор вызывает его один раз при финализации экземпляра. Он вызывается либо сборщиком мусора (если экземпляр является частью изолированного цикла ссылок), либо непосредственно перед освобождением объекта. В любом случае гарантируется, что он будет вызван до попытки разорвать циклы ссылок, что обеспечивает нахождение объекта в корректном состоянии.649650[`tp_finalize`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_finalize) не должен изменять текущее состояние исключения; поэтому рекомендуемый способ написания нетривиального финализатора:651652```c653static void654local_finalize(PyObject *self)655{656    PyObject *error_type, *error_value, *error_traceback;657658    /* Сохранить текущее исключение, если оно есть. */659    PyErr_Fetch(&error_type, &error_value, &error_traceback);660661    /* ... */662663    /* Восстановить сохранённое исключение. */664    PyErr_Restore(error_type, error_value, error_traceback);665}666```667668Чтобы это поле учитывалось (даже при наследовании), необходимо также установить флаг [`Py_TPFLAGS_HAVE_FINALIZE`](https://python-all.ru/3.4/c-api/typeobj.html#Py_TPFLAGS_HAVE_FINALIZE).669670Это поле наследуется подтипами.671672Новое в версии 3.4.673674> **См. также**675>676> «Безопасная финализация объектов» ([**PEP 442**](https://python-all.ru/3.4/c-api/typeobj.html))677678**[PyObject](https://python-all.ru/3.4/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_cache`**679680Не используется. Не наследуется. Только для внутреннего использования.681682**[PyObject](https://python-all.ru/3.4/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_subclasses`**683684Список слабых ссылок на подклассы. Не наследуется. Только для внутреннего использования.685686**[PyObject](https://python-all.ru/3.4/c-api/structures.html#c.PyObject)\* `PyTypeObject.tp_weaklist`**687688Голова списка слабых ссылок для слабых ссылок на этот объект типа. Не наследуется. Только для внутреннего использования.689690Оставшиеся поля определяются только если определён макрос тестирования функциональности `COUNT_ALLOCS`, и предназначены только для внутреннего использования. Они dокументированы здесь для полноты. Ни одно из этих полей не наследуется подтипами.691692**Py\_ssize\_t `PyTypeObject.tp_allocs`**693694Количество выделений памяти.695696**Py\_ssize\_t `PyTypeObject.tp_frees`**697698Количество освобождений.699700**Py\_ssize\_t `PyTypeObject.tp_maxalloc`**701702Максимальное количество одновременно выделенных объектов.703704**[PyTypeObject](https://python-all.ru/3.4/c-api/type.html#c.PyTypeObject)\* `PyTypeObject.tp_next`**705706Указатель на следующий объект типа с ненулевым полем [`tp_allocs`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyTypeObject.tp_allocs).707708Также следует отметить, что в Python со сборкой мусора tp\_dealloc может вызываться из любого потока Python, а не только из того, который создал объект (если объект становится частью цикла подсчёта ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Это не проблема для вызовов Python API, поскольку поток, в котором вызывается tp\_dealloc, будет владеть глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект, в свою очередь, уничтожает объекты из какой-либо другой библиотеки C или C++, следует соблюдать осторожность, чтобы убедиться, что уничтожение этих объектов в потоке, вызвавшем tp\_dealloc, не нарушит никаких предположений библиотеки.709710# Структуры числовых объектов711712**`PyNumberMethods`**713714Эта структура содержит указатели на функции, которые объект использует для реализации числового протокола. Каждая функция используется одноимённой функцией, описанной в разделе [*Числовой протокол*](https://python-all.ru/3.4/c-api/number.html#number).715716Вот определение структуры:717718```c719typedef struct {720     binaryfunc nb_add;721     binaryfunc nb_subtract;722     binaryfunc nb_multiply;723     binaryfunc nb_remainder;724     binaryfunc nb_divmod;725     ternaryfunc nb_power;726     unaryfunc nb_negative;727     unaryfunc nb_positive;728     unaryfunc nb_absolute;729     inquiry nb_bool;730     unaryfunc nb_invert;731     binaryfunc nb_lshift;732     binaryfunc nb_rshift;733     binaryfunc nb_and;734     binaryfunc nb_xor;735     binaryfunc nb_or;736     unaryfunc nb_int;737     void *nb_reserved;738     unaryfunc nb_float;739740     binaryfunc nb_inplace_add;741     binaryfunc nb_inplace_subtract;742     binaryfunc nb_inplace_multiply;743     binaryfunc nb_inplace_remainder;744     ternaryfunc nb_inplace_power;745     binaryfunc nb_inplace_lshift;746     binaryfunc nb_inplace_rshift;747     binaryfunc nb_inplace_and;748     binaryfunc nb_inplace_xor;749     binaryfunc nb_inplace_or;750751     binaryfunc nb_floor_divide;752     binaryfunc nb_true_divide;753     binaryfunc nb_inplace_floor_divide;754     binaryfunc nb_inplace_true_divide;755756     unaryfunc nb_index;757} PyNumberMethods;758```759760> **Примечание**761>762> Бинарные и тернарные функции должны проверять тип всех своих операндов и выполнять необходимые преобразования (хотя бы один из операндов является экземпляром определённого типа). Если операция не определена для данных операндов, бинарные и тернарные функции должны вернуть `Py_NotImplemented`; если произошла другая ошибка, они должны вернуть `NULL` и установить исключение.763764> **Примечание**765>766> Поле `nb_reserved` всегда должно быть `NULL`. Ранее оно называлось `nb_long` и было переименовано в Python 3.0.1.767768# Структуры объектов отображения769770**`PyMappingMethods`**771772Эта структура хранит указатели на функции, которые объект использует для реализации протокола отображения. Она содержит три члена:773774**lenfunc `PyMappingMethods.mp_length`**775776Эта функция используется функциями [`PyMapping_Length()`](https://python-all.ru/3.4/c-api/mapping.html#c.PyMapping_Length) и [`PyObject_Size()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Size) и имеет ту же сигнатуру. Этот слот может быть установлен в *NULL*, если у объекта нет определённой длины.777778**binaryfunc `PyMappingMethods.mp_subscript`**779780Эта функция используется функцией [`PyObject_GetItem()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_GetItem) и имеет ту же сигнатуру. Этот слот должен быть заполнен, чтобы функция [`PyMapping_Check()`](https://python-all.ru/3.4/c-api/mapping.html#c.PyMapping_Check) возвращала `1`; в противном случае он может быть *NULL*.781782**objobjargproc `PyMappingMethods.mp_ass_subscript`**783784Эта функция используется функцией [`PyObject_SetItem()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_SetItem) и имеет ту же сигнатуру. Если этот слот равен *NULL*, объект не поддерживает присваивание по индексу.785786# Структуры объектов последовательностей787788**`PySequenceMethods`**789790Эта структура содержит указатели на функции, которые объект использует для реализации протокола последовательности.791792**lenfunc `PySequenceMethods.sq_length`**793794Эта функция используется функциями [`PySequence_Size()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_Size) и [`PyObject_Size()`](https://python-all.ru/3.4/c-api/object.html#c.PyObject_Size), и имеет ту же сигнатуру.795796**binaryfunc `PySequenceMethods.sq_concat`**797798Эта функция используется функцией [`PySequence_Concat()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_Concat) и имеет ту же сигнатуру. Она также используется оператором `+` после попытки числового сложения через слот `nb_add`.799800**ssizeargfunc `PySequenceMethods.sq_repeat`**801802Эта функция используется функцией [`PySequence_Repeat()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_Repeat) и имеет ту же сигнатуру. Она также используется оператором `*` после попытки числового умножения через слот `nb_multiply`.803804**ssizeargfunc `PySequenceMethods.sq_item`**805806Эта функция используется функцией [`PySequence_GetItem()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_GetItem) и имеет ту же сигнатуру. Этот слот должен быть заполнен, чтобы функция [`PySequence_Check()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_Check) возвращала `1`; в противном случае он может быть *NULL*.807808Отрицательные индексы обрабатываются следующим образом: если слот `sq_length` заполнен, он вызывается и длина последовательности используется для вычисления положительного индекса, который передаётся в `sq_item`. Если `sq_length` равен *NULL*, индекс передаётся в функцию как есть.809810**ssizeobjargproc `PySequenceMethods.sq_ass_item`**811812Эта функция используется функцией [`PySequence_SetItem()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_SetItem) и имеет ту же сигнатуру. Этот слот может быть оставлен равным *NULL*, если объект не поддерживает присваивание по индексу.813814**objobjproc `PySequenceMethods.sq_contains`**815816Эта функция может использоваться [`PySequence_Contains()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_Contains) и имеет ту же\\nсигнатуру. Этот слот можно оставить равным *NULL*; в этом случае\\n[`PySequence_Contains()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_Contains) просто обходит последовательность, пока не найдёт\\nсовпадение.817818**binaryfunc `PySequenceMethods.sq_inplace_concat`**819820Эта функция используется [`PySequence_InPlaceConcat()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_InPlaceConcat) и имеет ту же\\nсигнатуру. Она должна изменить свой первый операнд и вернуть его.821822**ssizeargfunc `PySequenceMethods.sq_inplace_repeat`**823824Эта функция используется [`PySequence_InPlaceRepeat()`](https://python-all.ru/3.4/c-api/sequence.html#c.PySequence_InPlaceRepeat) и имеет ту же\\nсигнатуру. Она должна изменить свой первый операнд и вернуть его.825826# Структуры объектов буфера827828**`PyBufferProcs`**829830Эта структура содержит указатели на функции, необходимые для [*протокола буфера*](https://python-all.ru/3.4/c-api/buffer.html#bufferobjects). Протокол определяет, как объект-экспортёр может предоставлять свои внутренние данные объектам-потребителям.831832**getbufferproc `PyBufferProcs.bf_getbuffer`**833834Сигнатура этой функции:835836```c837int (PyObject *exporter, Py_buffer *view, int flags);838```839840Обрабатывает запрос к *экспортёру* на заполнение *представления* в соответствии с *флагами*. За исключением пункта (3), реализация этой функции ОБЯЗАНА выполнить следующие шаги:8418421. Необходимо проверить, можно ли выполнить запрос. Если нет, возбудить `PyExc_BufferError`,\\nустановить `view->obj` в *NULL* и вернуть -1.8432. Заполнить запрошенные поля.8443. Увеличить внутренний счётчик числа экспортов.8454. Установить `view->obj` в *exporter* и увеличить `view->obj`.8465. Вернуть 0.847848Если *экспортёр* является частью цепочки или дерева поставщиков буферов, можно использовать две основные схемы:849850- Повторный экспорт: каждый элемент дерева выступает в роли экспортирующего объекта и\\nустанавливает `view->obj` в новую ссылку на самого себя.851- Перенаправление: запрос буфера перенаправляется корневому объекту дерева.\\nЗдесь `view->obj` будет новой ссылкой на корневой объект.852853Отдельные поля *представления* описаны в разделе [*Структура буфера*](https://python-all.ru/3.4/c-api/buffer.html#buffer-structure), правила, как экспортёр должен реагировать на конкретные запросы – в разделе [*Типы запросов буфера*](https://python-all.ru/3.4/c-api/buffer.html#buffer-request-types).854855Вся память, на которую указывают поля структуры [`Py_buffer`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer), принадлежит экспортёру и должна оставаться действительной, пока остаются потребители.\\n[`format`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.format), [`shape`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.shape),\\n[`strides`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.strides), [`suboffsets`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.suboffsets)\\nи [`internal`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.internal) доступны только для чтения потребителю.856857[`PyBuffer_FillInfo()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_FillInfo) предоставляет простой способ открыть простой байтовый буфер, правильно обрабатывая все типы запросов.858859[`PyObject_GetBuffer()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyObject_GetBuffer) представляет собой интерфейс для потребителя, который оборачивает эту функцию.860861**releasebufferproc `PyBufferProcs.bf_releasebuffer`**862863Сигнатура этой функции:864865```c866void (PyObject *exporter, Py_buffer *view);867```868869Обрабатывает запрос на освобождение ресурсов буфера. Если ресурсы не нужно освобождать, [`PyBufferProcs.bf_releasebuffer`](https://python-all.ru/3.4/c-api/typeobj.html#c.PyBufferProcs.bf_releasebuffer) может быть *NULL*. В противном случае стандартная реализация этой функции будет выполнять следующие необязательные шаги:8708711. Уменьшить внутренний счётчик числа экспортов.8722. Если счётчик равен 0, освободить всю память, связанную с *view*.873874Экспортёр ОБЯЗАН использовать поле [`internal`](https://python-all.ru/3.4/c-api/buffer.html#c.Py_buffer.internal) для отслеживания ресурсов, специфичных для буфера. Это поле гарантированно остаётся постоянным, в то время как потребитель МОЖЕТ передавать копию исходного буфера в качестве аргумента *view*.875876Эта функция НЕ ДОЛЖНА уменьшать `view->obj`, так как это делается автоматически в [`PyBuffer_Release()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_Release) (такая схема полезна для разрыва циклических ссылок).877878[`PyBuffer_Release()`](https://python-all.ru/3.4/c-api/buffer.html#c.PyBuffer_Release) представляет собой интерфейс для потребителя, который оборачивает эту функцию.879