typeobj.md
1> **Источник:** https://python-all.ru/3.10/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.10/c-api/type.html#c.PyTypeObject). Объекты типа можно обрабатывать с помощью любой из функций `PyObject_*` или `PyType_*`, но для большинства приложений Python они не представляют большого интереса. Эти объекты являются основой поведения объектов, поэтому они очень важны как для самого интерпретатора, так и для любых модулей расширения, реализующих новые типы.1011Объекты типа довольно велики по сравнению с большинством стандартных типов. Причина такого размера в том, что каждый объект типа хранит большое количество значений, в основном указателей на функции C, каждый из которых реализует небольшую часть функциональности типа. Поля объекта типа подробно рассматриваются в этом разделе. Поля будут описаны в порядке их появления в структуре.1213В дополнение к следующему краткому справочнику раздел [Примеры](https://python-all.ru/3.10/c-api/typeobj.html#typedef-examples) даёт представление о значении и использовании [`PyTypeObject`](https://python-all.ru/3.10/c-api/type.html#c.PyTypeObject).1415## Краткий справочник1617### “tp slots”1819| PyTypeObject Slot [1](https://python-all.ru/3.10/c-api/typeobj.html#slots) | [Тип](https://python-all.ru/3.10/c-api/typeobj.html#slot-typedefs-table) | специальные методы/атрибуты | Информация [2](https://python-all.ru/3.10/c-api/typeobj.html#cols) | | | |20| --- | --- | --- | --- | --- | --- | --- |21| O | T | D | I | | | |22| \<R\> [`tp_name`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_name) | const char \* | name | X | X | | |23| [`tp_basicsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) | [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) | | X | X | | X |24| [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) | [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) | | | X | | X |25| [`tp_dealloc`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dealloc) | [`destructor`](https://python-all.ru/3.10/c-api/typeobj.html#c.destructor) | | X | X | | X |26| [`tp_vectorcall_offset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_vectorcall_offset) | [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) | | | X | | X |27| ([`tp_getattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattr)) | [`getattrfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.getattrfunc) | getattribute\_\_, \_\_getattr | | | | G |28| ([`tp_setattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattr)) | [`setattrfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.setattrfunc) | setattr\_\_, \_\_delattr | | | | G |29| [`tp_as_async`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_async) | [`PyAsyncMethods`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyAsyncMethods) \* | [подслоты](https://python-all.ru/3.10/c-api/typeobj.html#sub-slots) | | | | % |30| [`tp_repr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_repr) | [`reprfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.reprfunc) | repr | X | X | | X |31| [`tp_as_number`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_number) | [`PyNumberMethods`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods) \* | [подслоты](https://python-all.ru/3.10/c-api/typeobj.html#sub-slots) | | | | % |32| [`tp_as_sequence`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_sequence) | [`PySequenceMethods`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods) \* | [подслоты](https://python-all.ru/3.10/c-api/typeobj.html#sub-slots) | | | | % |33| [`tp_as_mapping`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_mapping) | [`PyMappingMethods`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyMappingMethods) \* | [подслоты](https://python-all.ru/3.10/c-api/typeobj.html#sub-slots) | | | | % |34| [`tp_hash`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_hash) | [`hashfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.hashfunc) | hash | X | | | G |35| [`tp_call`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_call) | [`ternaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ternaryfunc) | call | | X | | X |36| [`tp_str`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_str) | [`reprfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.reprfunc) | str | X | | | X |37| [`tp_getattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattro) | [`getattrofunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.getattrofunc) | getattribute\_\_, \_\_getattr | X | X | | G |38| [`tp_setattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattro) | [`setattrofunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.setattrofunc) | setattr\_\_, \_\_delattr | X | X | | G |39| [`tp_as_buffer`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer) | [`PyBufferProcs`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyBufferProcs) \* | | | | | % |40| [`tp_flags`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_flags) | unsigned long | | X | X | | ? |41| [`tp_doc`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_doc) | const char \* | doc | X | X | | |42| [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) | [`traverseproc`](https://python-all.ru/3.10/c-api/gcsupport.html#c.traverseproc) | | | X | | G |43| [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) | [`inquiry`](https://python-all.ru/3.10/c-api/gcsupport.html#c.inquiry) | | | X | | G |44| [`tp_richcompare`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) | [`richcmpfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.richcmpfunc) | lt\_\_, \_\_le\_\_, \_\_eq\_\_, \_\_ne\_\_, \_\_gt\_\_, \_\_ge | X | | | G |45| [`tp_weaklistoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) | [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) | | | X | | ? |46| [`tp_iter`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_iter) | [`getiterfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.getiterfunc) | iter | | | | X |47| [`tp_iternext`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_iternext) | [`iternextfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.iternextfunc) | next | | | | X |48| [`tp_methods`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_methods) | [`PyMethodDef`](https://python-all.ru/3.10/c-api/structures.html#c.PyMethodDef) \[\] | | X | X | | |49| [`tp_members`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_members) | [`PyMemberDef`](https://python-all.ru/3.10/c-api/structures.html#c.PyMemberDef) \[\] | | | X | | |50| [`tp_getset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getset) | [`PyGetSetDef`](https://python-all.ru/3.10/c-api/structures.html#c.PyGetSetDef) \[\] | | X | X | | |51| [`tp_base`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_base) | [`PyTypeObject`](https://python-all.ru/3.10/c-api/type.html#c.PyTypeObject) \* | base | | | X | |52| [`tp_dict`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dict) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | dict | | | ? | |53| [`tp_descr_get`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_descr_get) | [`descrgetfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.descrgetfunc) | get | | | | X |54| [`tp_descr_set`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_descr_set) | [`descrsetfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.descrsetfunc) | set\_\_, \_\_delete | | | | X |55| [`tp_dictoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) | [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) | | | X | | ? |56| [`tp_init`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_init) | [`initproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.initproc) | init | X | X | | X |57| [`tp_alloc`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_alloc) | [`allocfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.allocfunc) | | X | | ? | ? |58| [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) | [`newfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.newfunc) | new | X | X | ? | ? |59| [`tp_free`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_free) | [`freefunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.freefunc) | | X | X | ? | ? |60| [`tp_is_gc`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_is_gc) | [`inquiry`](https://python-all.ru/3.10/c-api/gcsupport.html#c.inquiry) | | | X | | X |61| \<[`tp_bases`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_bases)\> | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | bases | | | ~ | |62| \<[`tp_mro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_mro)\> | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | mro | | | ~ | |63| \[[`tp_cache`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_cache)\] | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | | | | | |64| \[[`tp_subclasses`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_subclasses)\] | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | subclasses | | | | |65| \[[`tp_weaklist`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_weaklist)\] | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | | | | | |66| ([`tp_del`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_del)) | [`destructor`](https://python-all.ru/3.10/c-api/typeobj.html#c.destructor) | | | | | |67| \[[`tp_version_tag`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_version_tag)\] | unsigned int | | | | | |68| [`tp_finalize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_finalize) | [`destructor`](https://python-all.ru/3.10/c-api/typeobj.html#c.destructor) | del | | | | X |69| [`tp_vectorcall`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_vectorcall) | [`vectorcallfunc`](https://python-all.ru/3.10/c-api/call.html#c.vectorcallfunc) | | | | | |7071**[1](https://python-all.ru/3.10/c-api/typeobj.html#id1)**7273**()**: Имя слота в круглых скобках указывает, что оно (фактически) устарело.7475**\<\>**: Имена в угловых скобках должны быть изначально установлены в `NULL` и считаться только для чтения.7677**\[\]**: Имена в квадратных скобках предназначены только для внутреннего использования.7879**\<R\>** (в качестве префикса) означает, что поле обязательно (должно быть не-`NULL`).8081**[2](https://python-all.ru/3.10/c-api/typeobj.html#id2)**8283Столбцы:8485**“O”**: устанавливается на `PyBaseObject_Type`8687**“T”**: устанавливается на [`PyType_Type`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Type)8889**“D”**: значение по умолчанию (если слот установлен в `NULL`)9091```text92X - PyType_Ready sets this value if it is NULL93~ - PyType_Ready always sets this value (it should be NULL)94? - PyType_Ready may set this value depending on other slots9596Also see the inheritance column ("I").97```9899**“I”**: наследование100101```text102X - type slot is inherited via *PyType_Ready* if defined with a *NULL* value103% - the slots of the sub-struct are inherited individually104G - inherited, but only in combination with other slots; see the slot's description105? - it's complicated; see the slot's description106```107108Обратите внимание, что некоторые слоты фактически наследуются через обычную цепочку поиска атрибутов.109110### подслоты111112| Слот | [Тип](https://python-all.ru/3.10/c-api/typeobj.html#slot-typedefs-table) | специальные методы |113| --- | --- | --- |114| [`am_await`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyAsyncMethods.am_await) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | await |115| [`am_aiter`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyAsyncMethods.am_aiter) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | aiter |116| [`am_anext`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyAsyncMethods.am_anext) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | anext |117| [`am_send`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyAsyncMethods.am_send) | [`sendfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.sendfunc) | |118| | | |119| [`nb_add`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_add) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | add\_\_ \_\_radd |120| [`nb_inplace_add`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_add) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | iadd |121| [`nb_subtract`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_subtract) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | sub\_\_ \_\_rsub |122| [`nb_inplace_subtract`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_subtract) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | isub |123| [`nb_multiply`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_multiply) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | mul\_\_ \_\_rmul |124| [`nb_inplace_multiply`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_multiply) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | imul |125| [`nb_remainder`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_remainder) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | mod\_\_ \_\_rmod |126| [`nb_inplace_remainder`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_remainder) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | imod |127| [`nb_divmod`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_divmod) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | divmod\_\_ \_\_rdivmod |128| [`nb_power`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_power) | [`ternaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ternaryfunc) | pow\_\_ \_\_rpow |129| [`nb_inplace_power`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_power) | [`ternaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ternaryfunc) | ipow |130| [`nb_negative`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_negative) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | neg |131| [`nb_positive`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_positive) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | pos |132| [`nb_absolute`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_absolute) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | abs |133| [`nb_bool`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_bool) | [`inquiry`](https://python-all.ru/3.10/c-api/gcsupport.html#c.inquiry) | bool |134| [`nb_invert`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_invert) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | invert |135| [`nb_lshift`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_lshift) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | lshift\_\_ \_\_rlshift |136| [`nb_inplace_lshift`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_lshift) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | ilshift |137| [`nb_rshift`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_rshift) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | rshift\_\_ \_\_rrshift |138| [`nb_inplace_rshift`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_rshift) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | irshift |139| [`nb_and`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_and) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | and\_\_ \_\_rand |140| [`nb_inplace_and`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_and) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | iand |141| [`nb_xor`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_xor) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | xor\_\_ \_\_rxor |142| [`nb_inplace_xor`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_xor) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | ixor |143| [`nb_or`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_or) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | or\_\_ \_\_ror |144| [`nb_inplace_or`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_or) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | ior |145| [`nb_int`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_int) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | int |146| [`nb_reserved`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_reserved) | void \* | |147| [`nb_float`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_float) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | float |148| [`nb_floor_divide`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_floor_divide) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | floordiv |149| [`nb_inplace_floor_divide`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_floor_divide) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | ifloordiv |150| [`nb_true_divide`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_true_divide) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | truediv |151| [`nb_inplace_true_divide`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_true_divide) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | itruediv |152| [`nb_index`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_index) | [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | index |153| [`nb_matrix_multiply`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_matrix_multiply) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | matmul\_\_ \_\_rmatmul |154| [`nb_inplace_matrix_multiply`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_matrix_multiply) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | imatmul |155| | | |156| [`mp_length`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyMappingMethods.mp_length) | [`lenfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.lenfunc) | len |157| [`mp_subscript`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyMappingMethods.mp_subscript) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | getitem |158| [`mp_ass_subscript`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyMappingMethods.mp_ass_subscript) | [`objobjargproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.objobjargproc) | setitem\_\_, \_\_delitem |159| | | |160| [`sq_length`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_length) | [`lenfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.lenfunc) | len |161| [`sq_concat`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_concat) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | add |162| [`sq_repeat`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_repeat) | [`ssizeargfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ssizeargfunc) | mul |163| [`sq_item`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_item) | [`ssizeargfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ssizeargfunc) | getitem |164| [`sq_ass_item`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_ass_item) | [`ssizeobjargproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ssizeobjargproc) | setitem\_\_ \_\_delitem |165| [`sq_contains`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_contains) | [`objobjproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.objobjproc) | contains |166| [`sq_inplace_concat`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_inplace_concat) | [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | iadd |167| [`sq_inplace_repeat`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_inplace_repeat) | [`ssizeargfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ssizeargfunc) | imul |168| | | |169| [`bf_getbuffer`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyBufferProcs.bf_getbuffer) | [`getbufferproc()`](https://python-all.ru/3.10/c-api/typeobj.html#c.getbufferproc) | |170| [`bf_releasebuffer`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyBufferProcs.bf_releasebuffer) | [`releasebufferproc()`](https://python-all.ru/3.10/c-api/typeobj.html#c.releasebufferproc) | |171172### Синонимы типов слотов173174| typedef | Типы параметров | Тип возвращаемого значения |175| --- | --- | --- |176| [`allocfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.allocfunc) | [`PyTypeObject`](https://python-all.ru/3.10/c-api/type.html#c.PyTypeObject) \* [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |177| [`destructor`](https://python-all.ru/3.10/c-api/typeobj.html#c.destructor) | void \* | void |178| [`freefunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.freefunc) | void \* | void |179| [`traverseproc`](https://python-all.ru/3.10/c-api/gcsupport.html#c.traverseproc) | void \* [`visitproc`](https://python-all.ru/3.10/c-api/gcsupport.html#c.visitproc) void \* | int |180| [`newfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.newfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |181| [`initproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.initproc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | int |182| [`reprfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.reprfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |183| [`getattrfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.getattrfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* const char \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |184| [`setattrfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.setattrfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* const char \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | int |185| [`getattrofunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.getattrofunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |186| [`setattrofunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.setattrofunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | int |187| [`descrgetfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.descrgetfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |188| [`descrsetfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.descrsetfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | int |189| [`hashfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.hashfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | Py\_hash\_t |190| [`richcmpfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.richcmpfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* int | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |191| [`getiterfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.getiterfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |192| [`iternextfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.iternextfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |193| [`lenfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.lenfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) |194| [`getbufferproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.getbufferproc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`Py_buffer`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer) \* int | int |195| [`releasebufferproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.releasebufferproc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`Py_buffer`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer) \* | void |196| [`inquiry`](https://python-all.ru/3.10/c-api/gcsupport.html#c.inquiry) | void \* | int |197| [`unaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.unaryfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |198| [`binaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.binaryfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |199| [`ternaryfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ternaryfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |200| [`ssizeargfunc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ssizeargfunc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* |201| [`ssizeobjargproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.ssizeobjargproc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`Py_ssize_t`](https://python-all.ru/3.10/c-api/intro.html#c.Py_ssize_t) [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | int |202| [`objobjproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.objobjproc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | int |203| [`objobjargproc`](https://python-all.ru/3.10/c-api/typeobj.html#c.objobjargproc) | [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* [`PyObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject) \* | int |204205Подробнее см. [определения типов слотов](https://python-all.ru/3.10/c-api/typeobj.html#id6) ниже.206207## Определение PyTypeObject208209Определение структуры для [`PyTypeObject`](https://python-all.ru/3.10/c-api/type.html#c.PyTypeObject) можно найти в `Include/object.h`. Для удобства здесь повторяется определение, приведённое там:210211```c212typedef struct _typeobject {213 PyObject_VAR_HEAD214 const char *tp_name; /* Для вывода в формате "<module>.<name>" */215 Py_ssize_t tp_basicsize, tp_itemsize; /* Для выделения памяти */216217 /* Методы для реализации стандартных операций */218219 destructor tp_dealloc;220 Py_ssize_t tp_vectorcall_offset;221 getattrfunc tp_getattr;222 setattrfunc tp_setattr;223 PyAsyncMethods *tp_as_async; /* ранее известный как tp_compare (Python 2)224 или tp_reserved (Python 3) */225 reprfunc tp_repr;226227 /* Наборы методов для стандартных классов */228229 PyNumberMethods *tp_as_number;230 PySequenceMethods *tp_as_sequence;231 PyMappingMethods *tp_as_mapping;232233 /* Дополнительные стандартные операции (здесь для двоичной совместимости) */234235 hashfunc tp_hash;236 ternaryfunc tp_call;237 reprfunc tp_str;238 getattrofunc tp_getattro;239 setattrofunc tp_setattro;240241 /* Функции для доступа к объекту как к буферу ввода/вывода */242 PyBufferProcs *tp_as_buffer;243244 /* Флаги для определения наличия опциональных/расширенных возможностей */245 unsigned long tp_flags;246247 const char *tp_doc; /* Строка документации */248249 /* Назначенное значение в версии 2.0 */250 /* вызов функции для всех доступных объектов */251 traverseproc tp_traverse;252253 /* удаление ссылок на содержащиеся объекты */254 inquiry tp_clear;255256 /* Назначенное значение в версии 2.1 */257 /* расширенные сравнения */258 richcmpfunc tp_richcompare;259260 /* включение слабых ссылок */261 Py_ssize_t tp_weaklistoffset;262263 /* Итераторы */264 getiterfunc tp_iter;265 iternextfunc tp_iternext;266267 /* Дескриптор атрибутов и механизмы подклассов */268 struct PyMethodDef *tp_methods;269 struct PyMemberDef *tp_members;270 struct PyGetSetDef *tp_getset;271 // Сильная ссылка на тип в куче, заимствованная ссылка на статический тип272 struct _typeobject *tp_base;273 PyObject *tp_dict;274 descrgetfunc tp_descr_get;275 descrsetfunc tp_descr_set;276 Py_ssize_t tp_dictoffset;277 initproc tp_init;278 allocfunc tp_alloc;279 newfunc tp_new;280 freefunc tp_free; /* Низкоуровневая процедура освобождения памяти */281 inquiry tp_is_gc; /* Для PyObject_IS_GC */282 PyObject *tp_bases;283 PyObject *tp_mro; /* порядок разрешения методов */284 PyObject *tp_cache;285 PyObject *tp_subclasses;286 PyObject *tp_weaklist;287 destructor tp_del;288289 /* Метка версии кэша атрибутов типа. Добавлено в версии 2.6. */290 unsigned int tp_version_tag;291292 destructor tp_finalize;293 vectorcallfunc tp_vectorcall;294} PyTypeObject;295```296297## Слоты PyObject298299Структура объекта типа расширяет структуру [`PyVarObject`](https://python-all.ru/3.10/c-api/structures.html#c.PyVarObject). Поле `ob_size` используется для динамических типов (создаваемых с помощью `type_new()`, обычно вызываемого из инструкции class). Обратите внимание, что [`PyType_Type`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Type) (метатип) инициализирует [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), что означает, что его экземпляры (т.е. объекты типов) *должны* иметь поле `ob_size`.300301#### `Py_ssize_t PyObject.ob_refcnt`302303*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*304305Это счётчик ссылок объекта-типа, инициализируется значением `1` макросом `PyObject_HEAD_INIT`. Обратите внимание: для [статически выделенных объектов-типов](https://python-all.ru/3.10/c-api/typeobj.html#static-types) экземпляры типа (объекты, у которых `ob_type` указывает обратно на тип) *не* считаются ссылками. Но для [динамически выделенных объектов-типов](https://python-all.ru/3.10/c-api/typeobj.html#heap-types) экземпляры *действительно* считаются ссылками.306307**Наследование:**308309Это поле не наследуется подтипами.310311#### `PyTypeObject *PyObject.ob_type`312313*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*314315Это тип типа, иными словами, его метатип. Он инициализируется аргументом макроса `PyObject_HEAD_INIT`, и его значением обычно должно быть `&PyType_Type`. Однако для динамически загружаемых модулей расширения, которые должны работать на Windows (по крайней мере), компилятор сообщает, что это недопустимый инициализатор. Поэтому принято передавать `NULL` макросу `PyObject_HEAD_INIT` и явно инициализировать это поле в начале функции инициализации модуля, перед любыми другими действиями. Обычно это делается так:316317```c318Foo_Type.ob_type = &PyType_Type;319```320321Это должно быть сделано до создания любых экземпляров типа. [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready) проверяет, равен ли `ob_type` значению `NULL`, и если да, инициализирует его значением поля `ob_type` базового класса. [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready) не будет изменять это поле, если оно ненулевое.322323**Наследование:**324325Это поле наследуется подтипами.326327#### `PyObject *PyObject._ob_next`328329#### `PyObject *PyObject._ob_prev`330331Эти поля присутствуют только если определён макрос `Py_TRACE_REFS` (см. [`configure --with-trace-refs option`](https://python-all.ru/3.10/using/configure.html#cmdoption-with-trace-refs)).332333Их инициализация значением `NULL` выполняется макросом `PyObject_HEAD_INIT`. Для [статически размещённых объектов](https://python-all.ru/3.10/c-api/typeobj.html#static-types) эти поля всегда остаются `NULL`. Для [динамически размещённых объектов](https://python-all.ru/3.10/c-api/typeobj.html#heap-types) эти два поля используются для включения объекта в двусвязный список *всех* живых объектов в куче.334335Это можно использовать для различных целей отладки; в настоящее время используется только в функции `sys.getobjects()` и для вывода объектов, которые остаются живыми в конце выполнения, когда установлена переменная окружения [`PYTHONDUMPREFS`](https://python-all.ru/3.10/using/cmdline.html#envvar-PYTHONDUMPREFS).336337**Наследование:**338339Эти поля не наследуются подтипами.340341## Слоты PyVarObject342343#### `Py_ssize_t PyVarObject.ob_size`344345*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*346347Для [статически выделенных объектов типов](https://python-all.ru/3.10/c-api/typeobj.html#static-types) это поле должно быть инициализировано нулём. Для [динамически выделенных объектов типов](https://python-all.ru/3.10/c-api/typeobj.html#heap-types) это поле имеет особый внутренний смысл.348349**Наследование:**350351Это поле не наследуется подтипами.352353## Слоты PyTypeObject354355Каждый слот имеет раздел, описывающий наследование. Если [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready) может устанавливать значение, когда поле установлено в `NULL`, то также будет раздел «Default» (значение по умолчанию). (Обратите внимание, что многие поля, заданные в `PyBaseObject_Type` и [`PyType_Type`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Type), фактически действуют как значения по умолчанию.)356357#### `const char *PyTypeObject.tp_name`358359Указатель на строку, завершающуюся NUL, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов это должно быть просто имя типа. Если модуль является подмодулем пакета, полное имя пакета является частью полного имени модуля. Например, тип с именем `T`, определённый в модуле `M` в подпакете `Q` пакета `P`, должен иметь инициализатор [`tp_name`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_name) со значением `"P.Q.M.T"`.360361Для [динамически выделенных объектов типов](https://python-all.ru/3.10/c-api/typeobj.html#heap-types) это должно быть просто имя типа, а имя модуля должно быть явно сохранено в словаре типа как значение для ключа `'__module__'`.362363Для [статически размещённых объектов типов](https://python-all.ru/3.10/c-api/typeobj.html#static-types), поле *tp\_name* должно содержать точку. Всё до последней точки становится доступно как атрибут `__module__`, а всё после последней точки – как атрибут [`__name__`](https://python-all.ru/3.10/library/stdtypes.html#definition.__name__).364365Если точка отсутствует, всё поле [`tp_name`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_name) становится доступным как атрибут [`__name__`](https://python-all.ru/3.10/library/stdtypes.html#definition.__name__), а атрибут `__module__` не определён (если только не задан явно в словаре, как описано выше). Это означает, что ваш тип невозможно будет сериализовать с помощью pickle. Кроме того, он не будет отображаться в документации модуля, создаваемой pydoc.366367Это поле не должно быть `NULL`. Это единственное обязательное поле в [`PyTypeObject()`](https://python-all.ru/3.10/c-api/type.html#c.PyTypeObject) (кроме потенциально [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize)).368369**Наследование:**370371Это поле не наследуется подтипами.372373#### `Py_ssize_t PyTypeObject.tp_basicsize`374375#### `Py_ssize_t PyTypeObject.tp_itemsize`376377Эти поля позволяют вычислить размер экземпляров типа в байтах.378379Существует два вида типов: типы с экземплярами фиксированной длины имеют нулевое [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) поле, типы с экземплярами переменной длины имеют ненулевое [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) поле. Для типа с экземплярами фиксированной длины все экземпляры имеют одинаковый размер, указанный в [`tp_basicsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).380381Для типа с экземплярами переменной длины экземпляры должны иметь `ob_size` поле, а размер экземпляра равен [`tp_basicsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) плюс N умножить на [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), где N – «длина» объекта. Значение N обычно хранится в поле `ob_size` экземпляра. Есть исключения: например, int использует отрицательное `ob_size` для обозначения отрицательного числа, и N равно `abs(ob_size)`. Кроме того, наличие поля `ob_size` в структуре экземпляра не означает, что структура экземпляра имеет переменную длину (например, структура для типа списка имеет экземпляры фиксированной длины, но при этом у этих экземпляров есть значимое поле `ob_size`).382383Базовый размер включает поля того экземпляра, которые объявлены макросом [`PyObject_HEAD`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject_HEAD) или [`PyObject_VAR_HEAD`](https://python-all.ru/3.10/c-api/structures.html#c.PyObject_VAR_HEAD) (в зависимости от того, какой из них используется для объявления структуры экземпляра), и он, в свою очередь, включает поля `_ob_prev` и `_ob_next`, если они присутствуют. Это означает, что единственный правильный способ получить инициализатор для [`tp_basicsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) – это использовать оператор `sizeof` для структуры, используемой для объявления макета экземпляра. Базовый размер не включает размер заголовка GC.384385Замечание о выравнивании: если переменные элементы требуют определённого выравнивания, это должно быть обеспечено значением [`tp_basicsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize). Пример: предположим, тип реализует массив `double`. [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) равно `sizeof(double)`. Программист должен гарантировать, что [`tp_basicsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) кратно `sizeof(double)` (при условии, что это и есть требование выравнивания для `double`).386387Для любого типа с экземплярами переменной длины это поле не должно быть `NULL`.388389**Наследование:**390391Эти поля наследуются подтипами независимо друг от друга. Если базовый тип имеет ненулевое [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize), обычно небезопасно устанавливать [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) в другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).392393#### `destructor PyTypeObject.tp_dealloc`394395Указатель на функцию-деструктор экземпляра. Эта функция должна быть определена, если только тип не гарантирует, что его экземпляры никогда не будут освобождены (как в случае с синглетонами `None` и `Ellipsis`). Сигнатура функции:396397```c398void tp_dealloc(PyObject *self);399```400401Функция-деструктор вызывается макросами [`Py_DECREF()`](https://python-all.ru/3.10/c-api/refcounting.html#c.Py_DECREF) и [`Py_XDECREF()`](https://python-all.ru/3.10/c-api/refcounting.html#c.Py_XDECREF), когда новое значение счётчика ссылок становится нулевым. В этот момент экземпляр всё ещё существует, но на него нет ссылок. Функция-деструктор должна освободить все ссылки, которыми владеет экземпляр, освободить все буферы памяти, принадлежащие экземпляру (с использованием функции освобождения, соответствующей функции выделения, использованной для выделения буфера), и вызвать функцию [`tp_free`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_free) типа. Если тип не является субтипируемым (не имеет установленного флага [`Py_TPFLAGS_BASETYPE`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_BASETYPE)), допускается вызывать деаллокатор объекта напрямую, а не через [`tp_free`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_free). Деаллокатор объекта должен быть тем же, что использовался для выделения экземпляра; обычно это [`PyObject_Del()`](https://python-all.ru/3.10/c-api/allocation.html#c.PyObject_Del), если экземпляр был выделен с помощью [`PyObject_New()`](https://python-all.ru/3.10/c-api/allocation.html#c.PyObject_New) или `PyObject_VarNew()`, или [`PyObject_GC_Del()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.PyObject_GC_Del), если экземпляр был выделен с помощью [`PyObject_GC_New()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.PyObject_GC_New) или [`PyObject_GC_NewVar()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.PyObject_GC_NewVar).402403Если тип поддерживает сборку мусора (имеет установленный флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) ), деструктор должен вызвать [`PyObject_GC_UnTrack()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.PyObject_GC_UnTrack) перед очисткой любых полей-членов.404405```c406static void foo_dealloc(foo_object *self) {407 PyObject_GC_UnTrack(self);408 Py_CLEAR(self->ref);409 Py_TYPE(self)->tp_free((PyObject *)self);410}411```412413Наконец, если тип выделен в куче ([`Py_TPFLAGS_HEAPTYPE`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HEAPTYPE)), деаллокатор должен освободить принадлежащую ему ссылку на объект-тип (через [`Py_DECREF()`](https://python-all.ru/3.10/c-api/refcounting.html#c.Py_DECREF)) после вызова деаллокатора типа. Чтобы избежать висячих указателей, рекомендуемый способ сделать это:414415```c416static void foo_dealloc(foo_object *self) {417 PyTypeObject *tp = Py_TYPE(self);418 // Освободить ссылки и буферы здесь.419 tp->tp_free(self);420 Py_DECREF(tp);421}422```423424**Наследование:**425426Это поле наследуется подтипами.427428#### `Py_ssize_t PyTypeObject.tp_vectorcall_offset`429430Необязательное смещение к поинстансной функции, реализующей вызов объекта с помощью [протокола vectorcall](https://python-all.ru/3.10/c-api/call.html#vectorcall), более эффективная альтернатива более простому [`tp_call`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_call).431432Это поле используется только в том случае, если установлен флаг [`Py_TPFLAGS_HAVE_VECTORCALL`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_VECTORCALL) . В этом случае оно должно быть положительным целым числом, содержащим смещение в экземпляре указателя [`vectorcallfunc`](https://python-all.ru/3.10/c-api/call.html#c.vectorcallfunc).433434Указатель *vectorcallfunc* может быть `NULL`, и в этом случае экземпляр ведёт себя так, как если бы [`Py_TPFLAGS_HAVE_VECTORCALL`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_VECTORCALL) не был установлен: вызов экземпляра сводится к [`tp_call`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_call).435436Любой класс, устанавливающий `Py_TPFLAGS_HAVE_VECTORCALL`, должен также установить [`tp_call`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_call) и убедиться, что его поведение согласуется с функцией *vectorcallfunc*. Это можно сделать, установив *tp\_call* в [`PyVectorcall_Call()`](https://python-all.ru/3.10/c-api/call.html#c.PyVectorcall_Call).437438> **Предупреждение**439>440> Не рекомендуется для [heap-типов](https://python-all.ru/3.10/c-api/typeobj.html#heap-types) реализовывать протокол vectorcall. Когда пользователь устанавливает `__call__` в коде Python, обновляется только *tp\_call*, что, скорее всего, делает его несовместимым с функцией vectorcall.441442Изменено в версии 3.8: До версии 3.8 этот слот назывался `tp_print`. В Python 2.x он использовался для вывода в файл. В Python 3.0–3.7 он не использовался.443444**Наследование:**445446Это поле всегда наследуется. Однако флаг [`Py_TPFLAGS_HAVE_VECTORCALL`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_VECTORCALL) наследуется не всегда. Если нет, то подкласс не будет использовать [vectorcall](https://python-all.ru/3.10/c-api/call.html#vectorcall), за исключением случаев, когда [`PyVectorcall_Call()`](https://python-all.ru/3.10/c-api/call.html#c.PyVectorcall_Call) вызывается явно. Это особенно характерно для [heap-типов](https://python-all.ru/3.10/c-api/typeobj.html#heap-types) (включая подклассы, определенные в Python).447448#### `getattrfunc PyTypeObject.tp_getattr`449450Необязательный указатель на функцию получения строки атрибута.451452Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция [`tp_getattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattro), но принимает C-строку вместо строкового объекта Python для указания имени атрибута.453454**Наследование:**455456Группа: `tp_getattr`, `tp_getattro`457458Это поле наследуется подтипами вместе с [`tp_getattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattro): подтип наследует и [`tp_getattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattr), и [`tp_getattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattr) и [`tp_getattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattro) подтипа оба равны `NULL`.459460#### `setattrfunc PyTypeObject.tp_setattr`461462Необязательный указатель на функцию для установки и удаления атрибутов.463464Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция [`tp_setattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattro), но принимает C-строку вместо строкового объекта Python для указания имени атрибута.465466**Наследование:**467468Группа: `tp_setattr`, `tp_setattro`469470Это поле наследуется подтипами вместе с [`tp_setattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattro): подтип наследует и [`tp_setattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattr), и [`tp_setattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattro) от своего базового типа, когда [`tp_setattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattr) и [`tp_setattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattro) подтипа оба равны `NULL`.471472#### `PyAsyncMethods *PyTypeObject.tp_as_async`473474Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протоколы [ожидаемого объекта](https://python-all.ru/3.10/glossary.html#term-awaitable) и [асинхронного итератора](https://python-all.ru/3.10/glossary.html#term-asynchronous-iterator) на уровне C. Подробнее см. в [Структуры асинхронных объектов](https://python-all.ru/3.10/c-api/typeobj.html#async-structs).475476Новое в версии 3.5: Ранее было известно как `tp_compare` и `tp_reserved`.477478**Наследование:**479480Поле [`tp_as_async`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_async) не наследуется, но содержащиеся в нем поля наследуются по отдельности.481482#### `reprfunc PyTypeObject.tp_repr`483484Необязательный указатель на функцию, реализующую встроенную функцию [`repr()`](https://python-all.ru/3.10/library/functions.html#repr).485486Сигнатура такая же, как для [`PyObject_Repr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_Repr):487488```c489PyObject *tp_repr(PyObject *self);490```491492Функция должна возвращать строку или объект Unicode. В идеале она должна возвращать строку, которая при передаче в [`eval()`](https://python-all.ru/3.10/library/functions.html#eval) в подходящем окружении возвращает объект с тем же значением. Если это невозможно, она должна возвращать строку, начинающуюся с `'<'` и заканчивающуюся `'>'`, из которой можно вывести как тип, так и значение объекта.493494**Наследование:**495496Это поле наследуется подтипами.497498**По умолчанию:**499500Если это поле не задано, возвращается строка вида `<%s object at %p>`, где `%s` заменяется именем типа, а `%p` – адресом памяти объекта.501502#### `PyNumberMethods *PyTypeObject.tp_as_number`503504Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих числовой протокол. Эти поля описаны в [Структуры числовых объектов](https://python-all.ru/3.10/c-api/typeobj.html#number-structs).505506**Наследование:**507508Поле [`tp_as_number`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_number) не наследуется, но содержащиеся в нём поля наследуются по отдельности.509510#### `PySequenceMethods *PyTypeObject.tp_as_sequence`511512Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол последовательности. Эти поля описаны в [Структуры объектов-последовательностей](https://python-all.ru/3.10/c-api/typeobj.html#sequence-structs).513514**Наследование:**515516Поле [`tp_as_sequence`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_sequence) не наследуется, но содержащиеся в нём поля наследуются по отдельности.517518#### `PyMappingMethods *PyTypeObject.tp_as_mapping`519520Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол отображения. Эти поля описаны в [Структуры объектов-отображений](https://python-all.ru/3.10/c-api/typeobj.html#mapping-structs).521522**Наследование:**523524Поле [`tp_as_mapping`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_mapping) не наследуется, но содержащиеся в нём поля наследуются по отдельности.525526#### `hashfunc PyTypeObject.tp_hash`527528Необязательный указатель на функцию, реализующую встроенную функцию [`hash()`](https://python-all.ru/3.10/library/functions.html#hash).529530Сигнатура такая же, как для [`PyObject_Hash()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_Hash):531532```c533Py_hash_t tp_hash(PyObject *);534```535536Значение `-1` не должно возвращаться как обычное возвращаемое значение; при возникновении ошибки во время вычисления хеш-значения функция должна установить исключение и вернуть `-1`.537538Если это поле не задано (*и* `tp_richcompare` не задано), то попытка получить хеш объекта вызывает [`TypeError`](https://python-all.ru/3.10/library/exceptions.html#TypeError). Это то же самое, что установить его в [`PyObject_HashNotImplemented()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_HashNotImplemented).539540Это поле можно явно установить в [`PyObject_HashNotImplemented()`](https://python-all.ru/3.10/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.10/c-api/object.html#c.PyObject_HashNotImplemented).541542**Наследование:**543544Группа: `tp_hash`, `tp_richcompare`545546Это поле наследуется подтипами вместе с [`tp_richcompare`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_richcompare): подтип наследует как [`tp_richcompare`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_richcompare), так и [`tp_hash`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_hash), если [`tp_richcompare`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа равны `NULL`.547548#### `ternaryfunc PyTypeObject.tp_call`549550Необязательный указатель на функцию, реализующую вызов объекта. Это значение должно быть `NULL`, если объект не является вызываемым. Сигнатура такая же, как у [`PyObject_Call()`](https://python-all.ru/3.10/c-api/call.html#c.PyObject_Call):551552```c553PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwargs);554```555556**Наследование:**557558Это поле наследуется подтипами.559560#### `reprfunc PyTypeObject.tp_str`561562Необязательный указатель на функцию, реализующую встроенную операцию [`str()`](https://python-all.ru/3.10/library/stdtypes.html#str). (Обратите внимание, что [`str`](https://python-all.ru/3.10/library/stdtypes.html#str) теперь является типом, а [`str()`](https://python-all.ru/3.10/library/stdtypes.html#str) вызывает конструктор этого типа. Этот конструктор вызывает [`PyObject_Str()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_Str) для выполнения фактической работы, и [`PyObject_Str()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_Str) будет вызывать этот обработчик.)563564Сигнатура такая же, как для [`PyObject_Str()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_Str):565566```c567PyObject *tp_str(PyObject *self);568```569570Функция должна возвращать строку или объект Unicode. Это должно быть «дружественное» строковое представление объекта, так как это представление будет использоваться, в частности, функцией [`print()`](https://python-all.ru/3.10/library/functions.html#print).571572**Наследование:**573574Это поле наследуется подтипами.575576**По умолчанию:**577578Если это поле не задано, вызывается [`PyObject_Repr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_Repr) для возврата строкового представления.579580#### `getattrofunc PyTypeObject.tp_getattro`581582Необязательный указатель на функцию получения атрибута.583584Сигнатура такая же, как для [`PyObject_GetAttr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GetAttr):585586```c587PyObject *tp_getattro(PyObject *self, PyObject *attr);588```589590Обычно удобно установить это поле в [`PyObject_GenericGetAttr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GenericGetAttr), которое реализует обычный способ поиска атрибутов объекта.591592**Наследование:**593594Группа: `tp_getattr`, `tp_getattro`595596Это поле наследуется подтипами вместе с [`tp_getattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattr): подтип наследует и [`tp_getattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattr), и [`tp_getattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattro) от своего базового типа, когда [`tp_getattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattr) и [`tp_getattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattro) подтипа оба равны `NULL`.597598**По умолчанию:**599600`PyBaseObject_Type` использует [`PyObject_GenericGetAttr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GenericGetAttr).601602#### `setattrofunc PyTypeObject.tp_setattro`603604Необязательный указатель на функцию для установки и удаления атрибутов.605606Сигнатура такая же, как для [`PyObject_SetAttr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_SetAttr):607608```c609int tp_setattro(PyObject *self, PyObject *attr, PyObject *value);610```611612Кроме того, установка *value* в `NULL` для удаления атрибута должна поддерживаться. Обычно удобно устанавливать это поле в [`PyObject_GenericSetAttr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GenericSetAttr), которое реализует обычный способ установки атрибутов объекта.613614**Наследование:**615616Группа: `tp_setattr`, `tp_setattro`617618Это поле наследуется подтипами вместе с [`tp_setattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattr): подтип наследует и [`tp_setattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattr), и [`tp_setattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattro) от своего базового типа, когда [`tp_setattr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattr) и [`tp_setattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattro) подтипа оба равны `NULL`.619620**По умолчанию:**621622`PyBaseObject_Type` использует [`PyObject_GenericSetAttr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GenericSetAttr).623624#### `PyBufferProcs *PyTypeObject.tp_as_buffer`625626Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих буферный интерфейс. Эти поля описаны в [Buffer Object Structures](https://python-all.ru/3.10/c-api/typeobj.html#buffer-structs).627628**Наследование:**629630Поле [`tp_as_buffer`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer) не наследуется, но содержащиеся в нем поля наследуются по отдельности.631632#### `unsigned long PyTypeObject.tp_flags`633634Это поле представляет собой битовую маску различных флагов. Некоторые флаги указывают на изменённую семантику для определённых ситуаций; другие используются для указания того, что определённые поля в объекте типа (или в расширяющих структурах, на которые ссылаются через [`tp_as_number`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_number), [`tp_as_sequence`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_sequence), [`tp_as_mapping`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_mapping) и [`tp_as_buffer`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_as_buffer)), которые исторически не всегда присутствовали, теперь действительны; если такой бит флага сброшен, то поля типа, которые он защищает, не должны использоваться и должны считаться имеющими значение ноль или `NULL`.635636**Наследование:**637638Наследование этого поля сложное. Большинство битов флагов наследуются индивидуально, т.е. если у базового типа установлен бит флага, подтип наследует этот бит флага. Биты флагов, относящиеся к расширяющим структурам, строго наследуются, если наследуется расширяющая структура, т.е. значение бита флага базового типа копируется в подтип вместе с указателем на расширяющую структуру. Бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) наследуется вместе с полями [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear), т.е. если бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) сброшен в подтипе, а поля [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) в подтипе существуют и имеют значения `NULL`.639640**По умолчанию:**641642`PyBaseObject_Type` использует `Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE`.643644**Битовые маски:**645646В настоящее время определены следующие битовые маски; их можно объединять с помощью оператора `|` для получения значения поля [`tp_flags`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_flags). Макрос [`PyType_HasFeature()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_HasFeature) принимает тип и значение флагов, *tp* и *f*, и проверяет, является ли `tp->tp_flags & f` ненулевым.647648#### `Py_TPFLAGS_HEAPTYPE`649650Этот бит устанавливается, когда сам объект типа выделен в куче, например, для типов, созданных динамически с помощью [`PyType_FromSpec()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_FromSpec). В этом случае поле `ob_type` его экземпляров считается ссылкой на тип, и при создании нового экземпляра для объекта типа вызывается INCREF, а при уничтожении экземпляра – DECREF (это не относится к экземплярам подтипов; только тип, на который ссылается ob\_type экземпляра, подвергается INCREF или DECREF).651652**Наследование:**653654???655656#### `Py_TPFLAGS_BASETYPE`657658Этот бит устанавливается, когда тип может использоваться как базовый тип другого типа. Если этот бит сброшен, тип не может быть унаследован (аналогично «финальному» классу в Java).659660**Наследование:**661662???663664#### `Py_TPFLAGS_READY`665666Этот бит устанавливается, когда объект типа был полностью инициализирован функцией [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready).667668**Наследование:**669670???671672#### `Py_TPFLAGS_READYING`673674Этот бит устанавливается, пока [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready) находится в процессе инициализации объекта типа.675676**Наследование:**677678???679680#### `Py_TPFLAGS_HAVE_GC`681682Этот бит устанавливается, когда объект поддерживает сборку мусора. Если бит установлен, экземпляры должны создаваться с помощью [`PyObject_GC_New()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.PyObject_GC_New) и уничтожаться с помощью [`PyObject_GC_Del()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.PyObject_GC_Del). Дополнительная информация – в разделе [Поддержка циклической сборки мусора](https://python-all.ru/3.10/c-api/gcsupport.html#supporting-cycle-detection). Этот бит также означает, что связанные со сборкой мусора поля [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) присутствуют в объекте типа.683684**Наследование:**685686Группа: [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC), `tp_traverse`, `tp_clear`687688Бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) наследуется вместе с полями `tp_traverse` и `tp_clear`, то есть если бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC) сброшен в подтипе, а поля `tp_traverse` и `tp_clear` в подтипе существуют и имеют значения `NULL`.689690#### `Py_TPFLAGS_DEFAULT`691692Это битовая маска всех битов, относящихся к наличию определённых полей в объекте типа и его структурах расширения. В настоящее время она включает следующие биты: `Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`.693694**Наследование:**695696???697698#### `Py_TPFLAGS_METHOD_DESCRIPTOR`699700Этот бит указывает, что объекты ведут себя как несвязанные методы.701702Если этот флаг установлен для `type(meth)`, то:703704- `meth.__get__(obj, cls)(*args, **kwds)` (при `obj` не None) должен быть эквивалентен `meth(obj, *args, **kwds)`.705- `meth.__get__(None, cls)(*args, **kwds)` должен быть эквивалентен `meth(*args, **kwds)`.706707Этот флаг включает оптимизацию для типичных вызовов методов, таких как `obj.meth()`: он позволяет избежать создания временного объекта «связанный метод» для `obj.meth`.708709Новое в версии 3.8.710711**Наследование:**712713Этот флаг никогда не наследуется [heap-типами](https://python-all.ru/3.10/c-api/typeobj.html#heap-types). Для типов расширения он наследуется всякий раз, когда наследуется [`tp_descr_get`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_descr_get).714715#### `Py_TPFLAGS_LONG_SUBCLASS`716717#### `Py_TPFLAGS_LIST_SUBCLASS`718719#### `Py_TPFLAGS_TUPLE_SUBCLASS`720721#### `Py_TPFLAGS_BYTES_SUBCLASS`722723#### `Py_TPFLAGS_UNICODE_SUBCLASS`724725#### `Py_TPFLAGS_DICT_SUBCLASS`726727#### `Py_TPFLAGS_BASE_EXC_SUBCLASS`728729#### `Py_TPFLAGS_TYPE_SUBCLASS`730731Эти флаги используются такими функциями, как [`PyLong_Check()`](https://python-all.ru/3.10/c-api/long.html#c.PyLong_Check), для быстрого определения, является ли тип подклассом встроенного типа; такие конкретные проверки выполняются быстрее, чем общая проверка, например [`PyObject_IsInstance()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_IsInstance). Пользовательские типы, наследующие от встроенных, должны иметь соответствующий [`tp_flags`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_flags) установленным, иначе код, взаимодействующий с такими типами, будет вести себя по-разному в зависимости от того, какая проверка используется.732733#### `Py_TPFLAGS_HAVE_FINALIZE`734735Этот бит устанавливается, когда слот [`tp_finalize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_finalize) присутствует в структуре типа.736737Новое в версии 3.4.738739Устарело с версии 3.8: Этот флаг больше не нужен, так как интерпретатор предполагает, что слот [`tp_finalize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_finalize) всегда присутствует в структуре типа.740741#### `Py_TPFLAGS_HAVE_VECTORCALL`742743Этот бит устанавливается, когда класс реализует [протокол vectorcall](https://python-all.ru/3.10/c-api/call.html#vectorcall). Подробнее см. [`tp_vectorcall_offset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_vectorcall_offset).744745**Наследование:**746747Этот бит наследуется для [статических подтипов](https://python-all.ru/3.10/c-api/typeobj.html#static-types), если [`tp_call`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_call) также наследуется. [Heap-типы](https://python-all.ru/3.10/c-api/typeobj.html#heap-types) не наследуют `Py_TPFLAGS_HAVE_VECTORCALL`.748749Новое в версии 3.9.750751#### `Py_TPFLAGS_IMMUTABLETYPE`752753Этот бит устанавливается для объектов типа, которые являются неизменяемыми: атрибуты типа нельзя ни установить, ни удалить.754755[`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready) автоматически применяет этот флаг к [статическим типам](https://python-all.ru/3.10/c-api/typeobj.html#static-types).756757**Наследование:**758759Этот флаг не наследуется.760761Новое в версии 3.10.762763#### `Py_TPFLAGS_DISALLOW_INSTANTIATION`764765Запретить создание экземпляров типа: установить [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) в NULL и не создавать ключ `__new__` в словаре типа.766767Флаг должен быть установлен до создания типа, а не после. Например, его нужно установить до вызова [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready) для этого типа.768769Флаг устанавливается автоматически для [статических типов](https://python-all.ru/3.10/c-api/typeobj.html#static-types), если [`tp_base`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_base) равен NULL или `&PyBaseObject_Type`, и [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) равен NULL.770771**Наследование:**772773Этот флаг не наследуется. Однако подклассы нельзя будет инстанцировать, если они не предоставят ненулевой [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) (что возможно только через C API).774775> **Примечание**776>777> Чтобы запретить прямое создание экземпляров класса, но разрешить создание его подклассов (например, для [абстрактного базового класса](https://python-all.ru/3.10/glossary.html#term-abstract-base-class)), не используйте этот флаг. Вместо этого добейтесь, чтобы [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) завершался успешно только для подклассов.778779Новое в версии 3.10.780781#### `Py_TPFLAGS_MAPPING`782783Этот бит указывает, что экземпляры класса могут сопоставляться с шаблонами отображений при использовании в качестве объекта оператора [`match`](https://python-all.ru/3.10/reference/compound_stmts.html#match). Он автоматически устанавливается при регистрации или наследовании [`collections.abc.Mapping`](https://python-all.ru/3.10/library/collections.abc.html#collections.abc.Mapping) и сбрасывается при регистрации [`collections.abc.Sequence`](https://python-all.ru/3.10/library/collections.abc.html#collections.abc.Sequence).784785> **Примечание**786>787> [`Py_TPFLAGS_MAPPING`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_MAPPING) и [`Py_TPFLAGS_SEQUENCE`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_SEQUENCE) взаимоисключающие; одновременная активация обоих флагов является ошибкой.788789**Наследование:**790791Этот флаг наследуется типами, которые ещё не установили [`Py_TPFLAGS_SEQUENCE`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_SEQUENCE).792793> **См. также**794>795> [**PEP 634**](https://python-all.ru/3.10/c-api/typeobj.html) – Структурное сопоставление с образцом: спецификация796797Новое в версии 3.10.798799#### `Py_TPFLAGS_SEQUENCE`800801Этот бит указывает, что экземпляры класса могут сопоставляться с шаблонами последовательностей при использовании в качестве объекта оператора [`match`](https://python-all.ru/3.10/reference/compound_stmts.html#match). Он автоматически устанавливается при регистрации или наследовании [`collections.abc.Sequence`](https://python-all.ru/3.10/library/collections.abc.html#collections.abc.Sequence) и сбрасывается при регистрации [`collections.abc.Mapping`](https://python-all.ru/3.10/library/collections.abc.html#collections.abc.Mapping).802803> **Примечание**804>805> [`Py_TPFLAGS_MAPPING`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_MAPPING) и [`Py_TPFLAGS_SEQUENCE`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_SEQUENCE) взаимоисключающие; одновременная активация обоих флагов является ошибкой.806807**Наследование:**808809Этот флаг наследуется типами, которые ещё не установили [`Py_TPFLAGS_MAPPING`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_MAPPING).810811> **См. также**812>813> [**PEP 634**](https://python-all.ru/3.10/c-api/typeobj.html) – Структурное сопоставление с образцом: спецификация814815Новое в версии 3.10.816817#### `const char *PyTypeObject.tp_doc`818819Необязательный указатель на C-строку, завершающуюся нулевым символом, содержащую строку документации для этого объекта типа. Это отображается как атрибут `__doc__` у типа и его экземпляров.820821**Наследование:**822823Это поле *не* наследуется подтипами.824825#### `traverseproc PyTypeObject.tp_traverse`826827Необязательный указатель на функцию обхода для сборщика мусора. Используется только если установлен бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Сигнатура:828829```c830int tp_traverse(PyObject *self, visitproc visit, void *arg);831```832833Дополнительная информация о схеме сборки мусора в Python доступна в разделе [Поддержка циклической сборки мусора](https://python-all.ru/3.10/c-api/gcsupport.html#supporting-cycle-detection).834835Указатель [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) используется сборщиком мусора для обнаружения циклических ссылок. Типичная реализация функции [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) просто вызывает [`Py_VISIT()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.Py_VISIT) для каждого элемента экземпляра, являющегося объектом Python, которым владеет экземпляр. Например, это функция `local_traverse()` из модуля расширения [`_thread`](https://python-all.ru/3.10/library/_thread.html#module-_thread):836837```c838static int839local_traverse(localobject *self, visitproc visit, void *arg)840{841 Py_VISIT(self->args);842 Py_VISIT(self->kw);843 Py_VISIT(self->dict);844 return 0;845}846```847848Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.Py_VISIT) вызывается только для тех членов, которые могут участвовать в циклических ссылках. Хотя есть также член `self->key`, он может быть только `NULL` или строкой Python и поэтому не может быть частью циклической ссылки.849850С другой стороны, даже если известно, что член никогда не может быть частью цикла, в качестве средства отладки его всё равно можно обойти, чтобы функция [`get_referents()`](https://python-all.ru/3.10/library/gc.html#gc.get_referents) модуля [`gc`](https://python-all.ru/3.10/library/gc.html#module-gc) включила его.851852> **Предупреждение**853>854> При реализации [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) должны обходиться только те члены, которыми экземпляр *владеет* (имея на них [сильные ссылки](https://python-all.ru/3.10/glossary.html#term-strong-reference)). Например, если объект поддерживает слабые ссылки через слот [`tp_weaklist`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_weaklist), указатель, поддерживающий связанный список (то, на что указывает *tp\_weaklist*), **не** должен обходиться, поскольку экземпляр не владеет напрямую слабыми ссылками на себя (список слабых ссылок существует для поддержки механизма слабых ссылок, но у экземпляра нет сильной ссылки на элементы внутри него, так как они могут быть удалены, даже если экземпляр всё ещё жив).855856Обратите внимание, что [`Py_VISIT()`](https://python-all.ru/3.10/c-api/gcsupport.html#c.Py_VISIT) требует, чтобы параметры *visit* и *arg* для `local_traverse()` имели именно такие имена; не следует называть их как попало.857858Экземпляры [кучевых типов](https://python-all.ru/3.10/c-api/typeobj.html#heap-types) содержат ссылку на свой тип. Поэтому их функция обхода должна либо обходить [`Py_TYPE(self)`](https://python-all.ru/3.10/c-api/structures.html#c.Py_TYPE), либо делегировать эту ответственность путём вызова `tp_traverse` другого кучевого типа (например, кучевого суперкласса). Если этого не сделать, объект типа может не быть собран сборщиком мусора.859860Изменено в версии 3.9: Ожидается, что типы, выделяемые в куче, будут посещать `Py_TYPE(self)` в `tp_traverse`. В более ранних версиях Python из-за [ошибки 40217](https://python-all.ru/3.10/c-api/typeobj.html) это могло приводить к сбоям в подклассах.861862**Наследование:**863864Группа: [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC), `tp_traverse`, `tp_clear`865866Это поле наследуется подтипами вместе с [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) и флагом [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): флаг, [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) наследуются от базового типа, если они равны нулю в подтипе.867868#### `inquiry PyTypeObject.tp_clear`869870Необязательный указатель на функцию очистки для сборщика мусора. Используется только если установлен флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Сигнатура:871872```c873int tp_clear(PyObject *);874```875876Функция-член [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) используется для разрыва циклических ссылок в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности все функции [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) в системе должны совместно разрывать все циклические ссылки. Это тонкий момент, и при любых сомнениях следует предоставить функцию [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear). Например, тип tuple не реализует функцию [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear), поскольку можно доказать, что ни одна циклическая ссылка не может состоять исключительно из кортежей. Поэтому функции [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) других типов должны быть достаточны для разрыва любой циклической ссылки, содержащей кортеж. Это не очевидно, и редко есть веская причина избегать реализации [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear).877878Реализации [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) должны удалять ссылки экземпляра на те его члены, которые могут являться объектами Python, и устанавливать указатели на эти члены в `NULL`, как показано в следующем примере:879880```c881static int882local_clear(localobject *self)883{884 Py_CLEAR(self->key);885 Py_CLEAR(self->args);886 Py_CLEAR(self->kw);887 Py_CLEAR(self->dict);888 return 0;889}890```891892Следует использовать макрос [`Py_CLEAR()`](https://python-all.ru/3.10/c-api/refcounting.html#c.Py_CLEAR), потому что очистка ссылок – это деликатная операция: ссылка на содержащийся объект не должна освобождаться (через [`Py_DECREF()`](https://python-all.ru/3.10/c-api/refcounting.html#c.Py_DECREF)) до тех пор, пока указатель на содержащийся объект не будет установлен в `NULL`. Это связано с тем, что освобождение ссылки может привести к тому, что содержащийся объект станет мусором, что вызовет цепочку действий по его утилизации, которая может включать выполнение произвольного кода Python (из-за финализаторов или колбэков слабых ссылок, связанных с содержащимся объектом). Если такой код может снова сослаться на *self*, важно, чтобы указатель на содержащийся объект в этот момент был `NULL`, чтобы *self* знал, что содержащийся объект больше нельзя использовать. Макрос [`Py_CLEAR()`](https://python-all.ru/3.10/c-api/refcounting.html#c.Py_CLEAR) выполняет операции в безопасном порядке.893894Обратите внимание, что [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) вызывается не *всегда* перед освобождением экземпляра. Например, когда подсчёта ссылок достаточно, чтобы определить, что объект больше не используется, циклический сборщик мусора не задействуется, и [`tp_dealloc`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dealloc) вызывается напрямую.895896Поскольку цель функций [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) – разрывать циклические ссылки, нет необходимости очищать содержащиеся объекты, такие как строки Python или целые числа Python, которые не могут участвовать в циклических ссылках. С другой стороны, может быть удобно очистить все содержащиеся объекты Python и написать функцию [`tp_dealloc`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dealloc) типа так, чтобы она вызывала [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear).897898Дополнительную информацию о схеме сборки мусора Python можно найти в разделе [Поддержка циклической сборки мусора](https://python-all.ru/3.10/c-api/gcsupport.html#supporting-cycle-detection).899900**Наследование:**901902Группа: [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC), `tp_traverse`, `tp_clear`903904Это поле наследуется подтипами вместе с [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и флагом [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC): флаг, [`tp_traverse`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_traverse) и [`tp_clear`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_clear) наследуются от базового типа, если они равны нулю в подтипе.905906#### `richcmpfunc PyTypeObject.tp_richcompare`907908Необязательный указатель на функцию расширенного сравнения, сигнатура которой:909910```c911PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);912```913914Первый параметр гарантированно является экземпляром типа, определяемого через [`PyTypeObject`](https://python-all.ru/3.10/c-api/type.html#c.PyTypeObject).915916Функция должна возвращать результат сравнения (обычно `Py_True` или `Py_False`). Если сравнение не определено, она должна вернуть `Py_NotImplemented`; если произошла другая ошибка, она должна вернуть `NULL` и установить условие исключения.917918Следующие константы определены для использования в качестве третьего аргумента для [`tp_richcompare`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и для [`PyObject_RichCompare()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_RichCompare):919920| Константа | Сравнение |921| --- | --- |922| `Py_LT` | `<` |923| `Py_LE` | `<=` |924| `Py_EQ` | `==` |925| `Py_NE` | `!=` |926| `Py_GT` | `>` |927| `Py_GE` | `>=` |928929Для упрощения написания функций расширенного сравнения определён следующий макрос:930931#### `Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)`932933Возвращает `Py_True` или `Py_False` из функции в зависимости от результата сравнения. VAL\_A и VAL\_B должны быть упорядочиваемыми с помощью операторов сравнения языка C (например, это могут быть значения типа int или float). Третий аргумент задаёт требуемую операцию, как и для [`PyObject_RichCompare()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_RichCompare).934935Возвращаемое значение – это новая [сильная ссылка](https://python-all.ru/3.10/glossary.html#term-strong-reference).936937В случае ошибки устанавливает исключение и возвращает `NULL` из функции.938939Добавлено в версии 3.7.940941**Наследование:**942943Группа: `tp_hash`, `tp_richcompare`944945Это поле наследуется подтипами вместе с [`tp_hash`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_hash): подтип наследует [`tp_richcompare`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_hash), когда [`tp_richcompare`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_richcompare) и [`tp_hash`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_hash) подтипа оба `NULL`.946947**По умолчанию:**948949`PyBaseObject_Type` предоставляет реализацию `tp_richcompare`, которая может быть унаследована. Однако, если определено только `tp_hash`, унаследованная функция не используется, и экземпляры типа не смогут участвовать в сравнениях.950951#### `Py_ssize_t PyTypeObject.tp_weaklistoffset`952953Если экземпляры этого типа поддерживают слабые ссылки, это поле больше нуля и содержит смещение в структуре экземпляра до головы списка слабых ссылок (игнорируя заголовок GC, если он присутствует); это смещение используется функциями [`PyObject_ClearWeakRefs()`](https://python-all.ru/3.10/c-api/weakref.html#c.PyObject_ClearWeakRefs) и `PyWeakref_*`. Структура экземпляра должна включать поле типа `PyObject*`, которое инициализируется значением `NULL`.954955Не путайте это поле с [`tp_weaklist`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_weaklist); это голова списка для слабых ссылок на сам объект типа.956957**Наследование:**958959Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что подтип использует другую голову списка слабых ссылок, нежели базовый тип. Поскольку голова списка всегда находится через [`tp_weaklistoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset), это не должно быть проблемой.960961Если тип, определённый с помощью оператора class, не содержит объявления [`__slots__`](https://python-all.ru/3.10/reference/datamodel.html#object.__slots__), и ни один из его базовых типов не поддерживает слабые ссылки, тип делается доступным для слабых ссылок: в компоновку экземпляра добавляется слот заголовка списка слабых ссылок, и [`tp_weaklistoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) устанавливается на смещение этого слота.962963Если объявление `__slots__` типа содержит слот с именем `__weakref__`, этот слот становится заголовком списка слабых ссылок для экземпляров типа, а его смещение сохраняется в поле [`tp_weaklistoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) типа.964965Если объявление `__slots__` типа не содержит слота с именем `__weakref__`, тип наследует значение [`tp_weaklistoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) от своего базового типа.966967#### `getiterfunc PyTypeObject.tp_iter`968969Необязательный указатель на функцию, возвращающую [итератор](https://python-all.ru/3.10/glossary.html#term-iterator) для объекта. Его наличие обычно означает, что экземпляры этого типа являются [итерируемыми](https://python-all.ru/3.10/glossary.html#term-iterable) (хотя последовательности могут быть итерируемыми и без этой функции).970971Эта функция имеет ту же сигнатуру, что и [`PyObject_GetIter()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GetIter):972973```c974PyObject *tp_iter(PyObject *self);975```976977**Наследование:**978979Это поле наследуется подтипами.980981#### `iternextfunc PyTypeObject.tp_iternext`982983Необязательный указатель на функцию, возвращающую следующий элемент [итератора](https://python-all.ru/3.10/glossary.html#term-iterator). Сигнатура:984985```c986PyObject *tp_iternext(PyObject *self);987```988989Когда итератор исчерпан, он должен возвращать `NULL`; исключение [`StopIteration`](https://python-all.ru/3.10/library/exceptions.html#StopIteration) может быть установлено или нет. При другой ошибке он также должен возвращать `NULL`. Его наличие означает, что экземпляры этого типа являются итераторами.990991Типы-итераторы также должны определять функцию [`tp_iter`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_iter), и эта функция должна возвращать сам экземпляр итератора (не новый экземпляр итератора).992993Эта функция имеет ту же сигнатуру, что и [`PyIter_Next()`](https://python-all.ru/3.10/c-api/iter.html#c.PyIter_Next).994995**Наследование:**996997Это поле наследуется подтипами.998999#### `struct PyMethodDef *PyTypeObject.tp_methods`10001001Необязательный указатель на статический массив структур [`PyMethodDef`](https://python-all.ru/3.10/c-api/structures.html#c.PyMethodDef), завершающийся `NULL`, объявляющий обычные методы этого типа.10021003Для каждой записи в массиве в словарь типа добавляется запись (см. [`tp_dict`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже), содержащая дескриптор метода.10041005**Наследование:**10061007Это поле не наследуется подтипами (методы наследуются через другой механизм).10081009#### `struct PyMemberDef *PyTypeObject.tp_members`10101011Необязательный указатель на статический массив [`PyMemberDef`](https://python-all.ru/3.10/c-api/structures.html#c.PyMemberDef) структур, завершающийся `NULL`, объявляющий обычные элементы данных (поля или слоты) экземпляров этого типа.10121013Для каждой записи в массиве в словарь типа добавляется запись, содержащая дескриптор члена (см. [`tp_dict`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже).10141015**Наследование:**10161017Это поле не наследуется подтипами (члены наследуются через другой механизм).10181019#### `struct PyGetSetDef *PyTypeObject.tp_getset`10201021Необязательный указатель на статический массив [`PyGetSetDef`](https://python-all.ru/3.10/c-api/structures.html#c.PyGetSetDef) структур, завершающийся `NULL`, объявляющий вычисляемые атрибуты экземпляров этого типа.10221023Для каждой записи в массиве в словарь типа добавляется запись, содержащая дескриптор getset (см. [`tp_dict`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dict) ниже).10241025**Наследование:**10261027Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).10281029#### `PyTypeObject *PyTypeObject.tp_base`10301031Необязательный указатель на базовый тип, от которого наследуются свойства типа. На этом уровне поддерживается только одиночное наследование; множественное наследование требует динамического создания объекта типа вызовом метатипа.10321033> **Примечание**1034>1035> Инициализация слотов подчиняется правилам инициализации глобальных переменных. C99 требует, чтобы инициализаторы были «адресными константами». Обозначения функций, такие как [`PyType_GenericNew()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_GenericNew), с неявным преобразованием в указатель, являются допустимыми адресными константами C99.1036>1037> Однако унарный оператор '&', применённый к нестатической переменной, такой как `PyBaseObject_Type()`, не обязан давать адресную константу. Компиляторы могут это поддерживать (gcc поддерживает), MSVC – нет. Оба компилятора в этом конкретном поведении строго соответствуют стандарту.1038>1039> Следовательно, [`tp_base`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_base) должно устанавливаться в функции инициализации модуля расширения.10401041**Наследование:**10421043Это поле не наследуется подтипами (очевидно).10441045**По умолчанию:**10461047По умолчанию это поле равно `&PyBaseObject_Type` (которое программистам Python известно как тип [`object`](https://python-all.ru/3.10/library/functions.html#object)).10481049#### `PyObject *PyTypeObject.tp_dict`10501051Словарь типа сохраняется здесь с помощью [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready).10521053Это поле обычно должно быть инициализировано значением `NULL` до вызова PyType\_Ready; его также можно инициализировать словарём с начальными атрибутами типа. После того, как [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready) инициализирует тип, дополнительные атрибуты можно добавлять в этот словарь только если они не соответствуют перегруженным операциям (например, `__add__()`).10541055**Наследование:**10561057Это поле не наследуется подтипами (хотя определённые здесь атрибуты наследуются через другой механизм).10581059**По умолчанию:**10601061Если это поле равно `NULL`, [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready) назначит ему новый словарь.10621063> **Предупреждение**1064>1065> Небезопасно использовать [`PyDict_SetItem()`](https://python-all.ru/3.10/c-api/dict.html#c.PyDict_SetItem) на или иным образом изменять [`tp_dict`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dict) с помощью C-API словаря.10661067#### `descrgetfunc PyTypeObject.tp_descr_get`10681069Необязательный указатель на функцию «descriptor get».10701071Сигнатура функции:10721073```c1074PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);1075```10761077**Наследование:**10781079Это поле наследуется подтипами.10801081#### `descrsetfunc PyTypeObject.tp_descr_set`10821083Необязательный указатель на функцию для установки и удаления значения дескриптора.10841085Сигнатура функции:10861087```c1088int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);1089```10901091Аргумент *value* устанавливается в `NULL` для удаления значения.10921093**Наследование:**10941095Это поле наследуется подтипами.10961097#### `Py_ssize_t PyTypeObject.tp_dictoffset`10981099Если экземпляры этого типа имеют словарь, содержащий переменные экземпляра, это поле не равно нулю и содержит смещение в структуре экземпляра для словаря переменных экземпляра; это смещение используется [`PyObject_GenericGetAttr()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GenericGetAttr).11001101Не путайте это поле с [`tp_dict`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dict); это словарь для атрибутов самого объекта типа.11021103Если значение этого поля больше нуля, оно задаёт смещение от начала структуры экземпляра. Если значение меньше нуля, оно задаёт смещение от *конца* структуры экземпляра. Использование отрицательного смещения обходится дороже, и его следует применять только в тех случаях, когда структура экземпляра содержит часть переменной длины. Это используется, например, для добавления словаря переменных экземпляра в подтипы [`str`](https://python-all.ru/3.10/library/stdtypes.html#str) или [`tuple`](https://python-all.ru/3.10/library/stdtypes.html#tuple). Обратите внимание, что поле [`tp_basicsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize) должно учитывать словарь, добавленный в конец в этом случае, даже если словарь не входит в базовую компоновку объекта. В системе с размером указателя 4 байта [`tp_dictoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) должно быть установлено в `-4`, чтобы указать, что словарь находится в самом конце структуры.11041105Реальное смещение словаря в экземпляре можно вычислить из отрицательного [`tp_dictoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) следующим образом:11061107```c1108dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset1109if dictoffset is not aligned on sizeof(void*):1110 round up to sizeof(void*)1111```11121113где [`tp_basicsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize), [`tp_itemsize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) и [`tp_dictoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) берутся из объекта типа, а `ob_size` берётся из экземпляра. Абсолютное значение берётся, потому что целые числа используют знак `ob_size` для хранения знака числа. (Никогда не требуется выполнять это вычисление самостоятельно; оно делается за вас функцией `_PyObject_GetDictPtr()`.)11141115**Наследование:**11161117Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что экземпляры подтипа хранят словарь по другому смещению, нежели базовый тип. Поскольку словарь всегда находится через [`tp_dictoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset), это не должно вызывать проблем.11181119Если тип, определённый с помощью оператора class, не содержит объявления [`__slots__`](https://python-all.ru/3.10/reference/datamodel.html#object.__slots__), и ни один из его базовых типов не имеет словаря переменных экземпляра, в компоновку экземпляра добавляется слот словаря, а [`tp_dictoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) устанавливается на смещение этого слота.11201121Если тип, определённый с помощью оператора class, содержит объявление `__slots__`, тот тип наследует значение [`tp_dictoffset`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) от своего базового типа.11221123(Добавление слота с именем [`__dict__`](https://python-all.ru/3.10/library/stdtypes.html#object.__dict__) в объявление `__slots__` не даёт ожидаемого эффекта, а только вызывает путаницу. Возможно, эту возможность стоит добавить как отдельную функцию, подобно `__weakref__`.)11241125**По умолчанию:**11261127Этот слот не имеет значения по умолчанию. Для [статических типов](https://python-all.ru/3.10/c-api/typeobj.html#static-types), если поле равно `NULL`, то для экземпляров не создаётся `__dict__`.11281129#### `initproc PyTypeObject.tp_init`11301131Необязательный указатель на функцию инициализации экземпляра.11321133Эта функция соответствует методу `__init__()` классов. Как и `__init__()`, можно создать экземпляр без вызова `__init__()`, и можно переинициализировать экземпляр, вызвав его метод `__init__()` ещё раз.11341135Сигнатура функции:11361137```c1138int tp_init(PyObject *self, PyObject *args, PyObject *kwds);1139```11401141Аргумент self – это инициализируемый экземпляр; аргументы *args* и *kwds* представляют позиционные и именованные аргументы вызова `__init__()`.11421143Функция [`tp_init`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_init), если она не `NULL`, вызывается при обычном создании экземпляра через вызов его типа, после того как функция [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) типа вернула экземпляр этого типа. Если функция [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) возвращает экземпляр другого типа, не являющегося подтипом исходного, функция [`tp_init`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_init) не вызывается; если [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) возвращает экземпляр подтипа исходного типа, вызывается [`tp_init`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_init) подтипа.11441145Возвращает `0` при успехе, `-1` и устанавливает исключение при ошибке.11461147**Наследование:**11481149Это поле наследуется подтипами.11501151**По умолчанию:**11521153Для [статических типов](https://python-all.ru/3.10/c-api/typeobj.html#static-types) это поле не имеет значения по умолчанию.11541155#### `allocfunc PyTypeObject.tp_alloc`11561157Необязательный указатель на функцию выделения экземпляра.11581159Сигнатура функции:11601161```c1162PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems);1163```11641165**Наследование:**11661167Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными с помощью инструкции class).11681169**По умолчанию:**11701171Для динамических подтипов это поле всегда устанавливается в [`PyType_GenericAlloc()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_GenericAlloc), чтобы принудительно применять стандартную стратегию выделения памяти из кучи.11721173Для статических подтипов `PyBaseObject_Type` использует [`PyType_GenericAlloc()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_GenericAlloc). Это рекомендуемое значение для всех статически определённых типов.11741175#### `newfunc PyTypeObject.tp_new`11761177Необязательный указатель на функцию создания экземпляра.11781179Сигнатура функции:11801181```c1182PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);1183```11841185Аргумент *subtype* – это тип создаваемого объекта; аргументы *args* и *kwds* представляют позиционные и ключевые аргументы вызова типа. Обратите внимание, что *subtype* не обязан совпадать с типом, чья функция [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) вызывается; это может быть подтип этого типа (но не произвольный тип).11861187Функция [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new) должна вызывать `subtype->tp_alloc(subtype, nitems)` для выделения памяти под объект, а затем выполнять лишь минимально необходимую инициализацию. Инициализацию, которую можно безопасно пропустить или повторить, следует помещать в обработчик [`tp_init`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_init). Хорошее эмпирическое правило: для неизменяемых типов вся инициализация должна выполняться в [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new), а для изменяемых типов большую часть инициализации лучше отложить до [`tp_init`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_init).11881189Флаг [`Py_TPFLAGS_DISALLOW_INSTANTIATION`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_DISALLOW_INSTANTIATION) используется для запрета создания экземпляров типа в Python.11901191**Наследование:**11921193Это поле наследуется подтипами, за исключением [статических типов](https://python-all.ru/3.10/c-api/typeobj.html#static-types), у которых [`tp_base`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_base) равно `NULL` или `&PyBaseObject_Type`.11941195**По умолчанию:**11961197Для [статических типов](https://python-all.ru/3.10/c-api/typeobj.html#static-types) это поле не имеет значения по умолчанию. Это означает, что если слот определён как `NULL`, тип нельзя вызвать для создания новых экземпляров; предположительно, существует другой способ создания экземпляров, например фабричная функция.11981199#### `freefunc PyTypeObject.tp_free`12001201Необязательный указатель на функцию освобождения экземпляра. Её сигнатура:12021203```c1204void tp_free(void *self);1205```12061207Инициализатор, совместимый с этой сигнатурой: [`PyObject_Free()`](https://python-all.ru/3.10/c-api/memory.html#c.PyObject_Free).12081209**Наследование:**12101211Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными через объявление класса).12121213**По умолчанию:**12141215В динамических подтипах это поле устанавливается в деаллокатор, подходящий для соответствия [`PyType_GenericAlloc()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_GenericAlloc) и значению флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).12161217Для статических подтипов `PyBaseObject_Type` использует PyObject\_Del.12181219#### `inquiry PyTypeObject.tp_is_gc`12201221Необязательный указатель на функцию, вызываемую сборщиком мусора.12221223Сборщику мусора необходимо знать, можно ли собрать конкретный объект или нет. Обычно достаточно посмотреть на поле [`tp_flags`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_flags) типа объекта и проверить бит флага [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC). Но некоторые типы содержат как статически, так и динамически выделенные экземпляры, и статически выделенные экземпляры не подлежат сборке. Такие типы должны определять эту функцию; она должна возвращать `1` для собираемого экземпляра и `0` для несобираемого. Сигнатура:12241225```c1226int tp_is_gc(PyObject *self);1227```12281229(Единственный пример этого – сами типы. Метакласс, [`PyType_Type`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Type), определяет эту функцию, чтобы различать статически и [динамически выделенные типы](https://python-all.ru/3.10/c-api/typeobj.html#heap-types).)12301231**Наследование:**12321233Это поле наследуется подтипами.12341235**По умолчанию:**12361237У этого слота нет значения по умолчанию. Если это поле равно `NULL`, то в качестве функционального эквивалента используется [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_GC).12381239#### `PyObject *PyTypeObject.tp_bases`12401241Кортеж базовых типов.12421243Это поле должно быть установлено в `NULL` и считаться доступным только для чтения. Python заполнит его, когда тип будет [`initialized`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready).12441245Для динамически создаваемых классов вместо аргумента *bases* из [`PyType_FromSpecWithBases()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_FromSpecWithBases) можно использовать `Py_tp_bases` [`slot`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Slot). Предпочтительна форма с аргументом.12461247> **Предупреждение**1248>1249> Множественное наследование плохо работает для статически определённых типов. Если установить `tp_bases` в кортеж, Python не вызовет ошибку, но некоторые слоты будут унаследованы только от первого базового класса.12501251**Наследование:**12521253Это поле не наследуется.12541255#### `PyObject *PyTypeObject.tp_mro`12561257Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая [`object`](https://python-all.ru/3.10/library/functions.html#object), в порядке разрешения методов (MRO).12581259Это поле должно быть установлено в `NULL` и считаться доступным только для чтения. Python заполнит его, когда тип будет [`initialized`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready).12601261**Наследование:**12621263Это поле не наследуется; оно вычисляется заново с помощью [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready).12641265#### `PyObject *PyTypeObject.tp_cache`12661267Не используется. Только для внутреннего использования.12681269**Наследование:**12701271Это поле не наследуется.12721273#### `PyObject *PyTypeObject.tp_subclasses`12741275Список слабых ссылок на подклассы. Только для внутреннего использования.12761277**Наследование:**12781279Это поле не наследуется.12801281#### `PyObject *PyTypeObject.tp_weaklist`12821283Голова списка слабых ссылок для слабых ссылок на этот объект типа. Не наследуется. Только для внутреннего использования.12841285**Наследование:**12861287Это поле не наследуется.12881289#### `destructor PyTypeObject.tp_del`12901291Это поле устарело. Используйте [`tp_finalize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_finalize) вместо него.12921293#### `unsigned int PyTypeObject.tp_version_tag`12941295Используется для индексации кэша методов. Только для внутреннего использования.12961297**Наследование:**12981299Это поле не наследуется.13001301#### `destructor PyTypeObject.tp_finalize`13021303Необязательный указатель на функцию финализации экземпляра. Её сигнатура:13041305```c1306void tp_finalize(PyObject *self);1307```13081309Если [`tp_finalize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_finalize) установлен, интерпретатор вызывает его один раз при финализации экземпляра. Он вызывается либо сборщиком мусора (если экземпляр является частью изолированного цикла ссылок), либо непосредственно перед освобождением объекта. В любом случае гарантируется, что он будет вызван до попытки разорвать циклы ссылок, что обеспечивает нахождение объекта в корректном состоянии.13101311[`tp_finalize`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_finalize) не должен изменять текущий статус исключения; поэтому рекомендуемый способ написания нетривиального финализатора:13121313```c1314static void1315local_finalize(PyObject *self)1316{1317 PyObject *error_type, *error_value, *error_traceback;13181319 /* Сохранить текущее исключение, если оно есть. */1320 PyErr_Fetch(&error_type, &error_value, &error_traceback);13211322 /* ... */13231324 /* Восстановить сохранённое исключение. */1325 PyErr_Restore(error_type, error_value, error_traceback);1326}1327```13281329Кроме того, обратите внимание, что в Python со сборкой мусора [`tp_dealloc`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_dealloc) может быть вызван из любого потока Python, а не только из потока, создавшего объект (если объект становится частью цикла ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Это не проблема для вызовов API Python, поскольку поток, в котором вызывается tp\_dealloc, владеет глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект в свою очередь уничтожает объекты из какой-либо другой библиотеки на C или C++, следует позаботиться о том, чтобы уничтожение этих объектов в потоке, вызвавшем tp\_dealloc, не нарушало никаких допущений библиотеки.13301331**Наследование:**13321333Это поле наследуется подтипами.13341335Новое в версии 3.4.13361337Изменено в версии 3.8: До версии 3.8 необходимо было установить бит флагов [`Py_TPFLAGS_HAVE_FINALIZE`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HAVE_FINALIZE), чтобы это поле можно было использовать. Теперь это не требуется.13381339> **См. также**1340>1341> «Безопасная финализация объектов» ([**PEP 442**](https://python-all.ru/3.10/c-api/typeobj.html))13421343#### `vectorcallfunc PyTypeObject.tp_vectorcall`13441345Функция vectorcall, используемая для вызовов этого объекта типа. Другими словами, она используется для реализации [vectorcall](https://python-all.ru/3.10/c-api/call.html#vectorcall) для `type.__call__`. Если `tp_vectorcall` равно `NULL`, используется реализация вызова по умолчанию с использованием `__new__` и `__init__`.13461347**Наследование:**13481349Это поле никогда не наследуется.13501351Новое в версии 3.9: (поле существует с версии 3.8, но используется только с версии 3.9)13521353## Статические типы13541355Традиционно типы, определяемые в коде C, являются *статическими*, то есть статическая структура [`PyTypeObject`](https://python-all.ru/3.10/c-api/type.html#c.PyTypeObject) определяется непосредственно в коде и инициализируется с помощью [`PyType_Ready()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Ready).13561357В результате получаются типы, которые ограничены по сравнению с типами, определёнными в Python.13581359- Статические типы ограничены одним базовым классом, то есть не могут использовать множественное наследование.1360- Объекты статических типов (но не обязательно их экземпляры) неизменяемы. Из Python невозможно добавить или изменить атрибуты объекта типа.1361- Объекты статических типов разделяются между [под-интерпретаторами](https://python-all.ru/3.10/c-api/init.html#sub-interpreter-support), поэтому они не должны содержать состояние, специфичное для под-интерпретатора.13621363Кроме того, поскольку [`PyTypeObject`](https://python-all.ru/3.10/c-api/type.html#c.PyTypeObject) является лишь частью [Limited API](https://python-all.ru/3.10/c-api/stable.html#stable) в виде непрозрачной структуры, любые модули расширения, использующие статические типы, должны быть скомпилированы для конкретной минорной версии Python.13641365## Кучные типы13661367Альтернативой [статическим типам](https://python-all.ru/3.10/c-api/typeobj.html#static-types) являются *кучные типы (heap-allocated types)*, или *кучные типы (heap types)* для краткости. Они очень похожи на классы, создаваемые с помощью оператора `class`. У кучных типов установлен флаг [`Py_TPFLAGS_HEAPTYPE`](https://python-all.ru/3.10/c-api/typeobj.html#Py_TPFLAGS_HEAPTYPE).13681369Для этого заполняется структура [`PyType_Spec`](https://python-all.ru/3.10/c-api/type.html#c.PyType_Spec) и вызывается [`PyType_FromSpec()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_FromSpec), [`PyType_FromSpecWithBases()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_FromSpecWithBases) или [`PyType_FromModuleAndSpec()`](https://python-all.ru/3.10/c-api/type.html#c.PyType_FromModuleAndSpec).13701371# Структуры числовых объектов13721373#### `type PyNumberMethods`13741375Эта структура содержит указатели на функции, которые объект использует для реализации числового протокола. Каждая функция используется одноимённой функцией, описанной в разделе [Числовой протокол](https://python-all.ru/3.10/c-api/number.html#number).13761377Вот определение структуры:13781379```c1380typedef struct {1381 binaryfunc nb_add;1382 binaryfunc nb_subtract;1383 binaryfunc nb_multiply;1384 binaryfunc nb_remainder;1385 binaryfunc nb_divmod;1386 ternaryfunc nb_power;1387 unaryfunc nb_negative;1388 unaryfunc nb_positive;1389 unaryfunc nb_absolute;1390 inquiry nb_bool;1391 unaryfunc nb_invert;1392 binaryfunc nb_lshift;1393 binaryfunc nb_rshift;1394 binaryfunc nb_and;1395 binaryfunc nb_xor;1396 binaryfunc nb_or;1397 unaryfunc nb_int;1398 void *nb_reserved;1399 unaryfunc nb_float;14001401 binaryfunc nb_inplace_add;1402 binaryfunc nb_inplace_subtract;1403 binaryfunc nb_inplace_multiply;1404 binaryfunc nb_inplace_remainder;1405 ternaryfunc nb_inplace_power;1406 binaryfunc nb_inplace_lshift;1407 binaryfunc nb_inplace_rshift;1408 binaryfunc nb_inplace_and;1409 binaryfunc nb_inplace_xor;1410 binaryfunc nb_inplace_or;14111412 binaryfunc nb_floor_divide;1413 binaryfunc nb_true_divide;1414 binaryfunc nb_inplace_floor_divide;1415 binaryfunc nb_inplace_true_divide;14161417 unaryfunc nb_index;14181419 binaryfunc nb_matrix_multiply;1420 binaryfunc nb_inplace_matrix_multiply;1421} PyNumberMethods;1422```14231424> **Примечание**1425>1426> Бинарные и тернарные функции должны проверять тип всех своих операндов и выполнять необходимые преобразования (хотя бы один из операндов должен быть экземпляром определяемого типа). Если операция не определена для данных операндов, бинарные и тернарные функции должны вернуть `Py_NotImplemented`; если произошла другая ошибка, они должны вернуть `NULL` и установить исключение.14271428> **Примечание**1429>1430> Поле [`nb_reserved`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_reserved) всегда должно быть `NULL`. Ранее оно называлось `nb_long` и было переименовано в Python 3.0.1.14311432#### `binaryfunc PyNumberMethods.nb_add`14331434#### `binaryfunc PyNumberMethods.nb_subtract`14351436#### `binaryfunc PyNumberMethods.nb_multiply`14371438#### `binaryfunc PyNumberMethods.nb_remainder`14391440#### `binaryfunc PyNumberMethods.nb_divmod`14411442#### `ternaryfunc PyNumberMethods.nb_power`14431444#### `unaryfunc PyNumberMethods.nb_negative`14451446#### `unaryfunc PyNumberMethods.nb_positive`14471448#### `unaryfunc PyNumberMethods.nb_absolute`14491450#### `inquiry PyNumberMethods.nb_bool`14511452#### `unaryfunc PyNumberMethods.nb_invert`14531454#### `binaryfunc PyNumberMethods.nb_lshift`14551456#### `binaryfunc PyNumberMethods.nb_rshift`14571458#### `binaryfunc PyNumberMethods.nb_and`14591460#### `binaryfunc PyNumberMethods.nb_xor`14611462#### `binaryfunc PyNumberMethods.nb_or`14631464#### `unaryfunc PyNumberMethods.nb_int`14651466#### `void *PyNumberMethods.nb_reserved`14671468#### `unaryfunc PyNumberMethods.nb_float`14691470#### `binaryfunc PyNumberMethods.nb_inplace_add`14711472#### `binaryfunc PyNumberMethods.nb_inplace_subtract`14731474#### `binaryfunc PyNumberMethods.nb_inplace_multiply`14751476#### `binaryfunc PyNumberMethods.nb_inplace_remainder`14771478#### `ternaryfunc PyNumberMethods.nb_inplace_power`14791480#### `binaryfunc PyNumberMethods.nb_inplace_lshift`14811482#### `binaryfunc PyNumberMethods.nb_inplace_rshift`14831484#### `binaryfunc PyNumberMethods.nb_inplace_and`14851486#### `binaryfunc PyNumberMethods.nb_inplace_xor`14871488#### `binaryfunc PyNumberMethods.nb_inplace_or`14891490#### `binaryfunc PyNumberMethods.nb_floor_divide`14911492#### `binaryfunc PyNumberMethods.nb_true_divide`14931494#### `binaryfunc PyNumberMethods.nb_inplace_floor_divide`14951496#### `binaryfunc PyNumberMethods.nb_inplace_true_divide`14971498#### `unaryfunc PyNumberMethods.nb_index`14991500#### `binaryfunc PyNumberMethods.nb_matrix_multiply`15011502#### `binaryfunc PyNumberMethods.nb_inplace_matrix_multiply`15031504# Структуры объектов отображения15051506#### `type PyMappingMethods`15071508Эта структура хранит указатели на функции, которые объект использует для реализации протокола отображения. Она содержит три члена:15091510#### `lenfunc PyMappingMethods.mp_length`15111512Эта функция используется [`PyMapping_Size()`](https://python-all.ru/3.10/c-api/mapping.html#c.PyMapping_Size) и [`PyObject_Size()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_Size) и имеет ту же сигнатуру. Этот слот может быть установлен в `NULL`, если у объекта нет определённой длины.15131514#### `binaryfunc PyMappingMethods.mp_subscript`15151516Эта функция используется [`PyObject_GetItem()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GetItem) и [`PySequence_GetSlice()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_GetSlice) и имеет ту же сигнатуру, что и `PyObject_GetItem()`. Этот слот должен быть заполнен, чтобы функция [`PyMapping_Check()`](https://python-all.ru/3.10/c-api/mapping.html#c.PyMapping_Check) возвращала `1`; в противном случае он может быть `NULL` .15171518#### `objobjargproc PyMappingMethods.mp_ass_subscript`15191520Эта функция используется [`PyObject_SetItem()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_SetItem), [`PyObject_DelItem()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_DelItem), `PyObject_SetSlice()` и `PyObject_DelSlice()`. У неё та же сигнатура, что и у `PyObject_SetItem()`, но *v* также может быть установлен в `NULL` для удаления элемента. Если этот слот равен `NULL`, объект не поддерживает присваивание и удаление элементов.15211522# Структуры объектов последовательностей15231524#### `type PySequenceMethods`15251526Эта структура содержит указатели на функции, которые объект использует для реализации протокола последовательности.15271528#### `lenfunc PySequenceMethods.sq_length`15291530Эта функция используется [`PySequence_Size()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_Size) и [`PyObject_Size()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_Size) и имеет ту же сигнатуру. Она также используется для обработки отрицательных индексов через слоты [`sq_item`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_item) и [`sq_ass_item`](https://python-all.ru/3.10/c-api/typeobj.html#c.PySequenceMethods.sq_ass_item).15311532#### `binaryfunc PySequenceMethods.sq_concat`15331534Эта функция используется [`PySequence_Concat()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_Concat) и имеет ту же сигнатуру. Она также используется оператором `+` после попытки численного сложения через слот [`nb_add`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_add).15351536#### `ssizeargfunc PySequenceMethods.sq_repeat`15371538Эта функция используется [`PySequence_Repeat()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_Repeat) и имеет ту же сигнатуру. Она также используется оператором `*` после попытки численного умножения через слот [`nb_multiply`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_multiply).15391540#### `ssizeargfunc PySequenceMethods.sq_item`15411542Эта функция используется [`PySequence_GetItem()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_GetItem) и имеет ту же сигнатуру. Она также используется [`PyObject_GetItem()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_GetItem) после попытки индексирования через слот [`mp_subscript`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyMappingMethods.mp_subscript). Этот слот должен быть заполнен, чтобы функция [`PySequence_Check()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_Check) возвращала `1`; в противном случае он может быть `NULL`.15431544Отрицательные индексы обрабатываются следующим образом: если слот `sq_length`\\nзаполнен, он вызывается, и длина последовательности используется для вычисления положительного\\nиндекса, который передаётся в `sq_item`. Если `sq_length` равно `NULL`,\\nиндекс передаётся функции как есть.15451546#### `ssizeobjargproc PySequenceMethods.sq_ass_item`15471548Эта функция используется [`PySequence_SetItem()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_SetItem) и имеет ту же сигнатуру. Она также используется [`PyObject_SetItem()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_SetItem) и [`PyObject_DelItem()`](https://python-all.ru/3.10/c-api/object.html#c.PyObject_DelItem) после попытки присваивания и удаления элемента через слот [`mp_ass_subscript`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyMappingMethods.mp_ass_subscript). Этот слот может быть оставлен равным `NULL`, если объект не поддерживает присваивание и удаление элементов.15491550#### `objobjproc PySequenceMethods.sq_contains`15511552Эта функция может использоваться [`PySequence_Contains()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_Contains) и имеет ту же сигнатуру. Этот слот может быть оставлен равным `NULL`; в этом случае `PySequence_Contains()` просто проходит по последовательности, пока не найдёт совпадение.15531554#### `binaryfunc PySequenceMethods.sq_inplace_concat`15551556Эта функция используется [`PySequence_InPlaceConcat()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_InPlaceConcat) и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его. Этот слот может быть оставлен равным `NULL`; в этом случае `PySequence_InPlaceConcat()` будет использовать [`PySequence_Concat()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_Concat) как запасной вариант. Она также используется расширенным присваиванием `+=` после попытки численного сложения на месте через слот [`nb_inplace_add`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_add).15571558#### `ssizeargfunc PySequenceMethods.sq_inplace_repeat`15591560Эта функция используется [`PySequence_InPlaceRepeat()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_InPlaceRepeat) и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его. Этот слот может быть оставлен равным `NULL`; в этом случае `PySequence_InPlaceRepeat()` будет использовать [`PySequence_Repeat()`](https://python-all.ru/3.10/c-api/sequence.html#c.PySequence_Repeat) как запасной вариант. Она также используется расширенным присваиванием `*=` после попытки численного умножения на месте через слот [`nb_inplace_multiply`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyNumberMethods.nb_inplace_multiply).15611562# Структуры объектов буфера15631564#### `type PyBufferProcs`15651566Эта структура содержит указатели на функции, необходимые для [протокола буфера](https://python-all.ru/3.10/c-api/buffer.html#bufferobjects). Протокол определяет, как объект-экспортёр может предоставлять свои внутренние данные объектам-потребителям.15671568#### `getbufferproc PyBufferProcs.bf_getbuffer`15691570Сигнатура этой функции:15711572```c1573int (PyObject *exporter, Py_buffer *view, int flags);1574```15751576Обрабатывает запрос к *экспортёру* на заполнение *представления* в соответствии с *флагами*. За исключением пункта (3), реализация этой функции ОБЯЗАНА выполнить следующие шаги:157715781. Проверить, можно ли удовлетворить запрос. Если нет, возбудить `PyExc_BufferError`, установить `view->obj` в `NULL` и вернуть `-1`.15792. Заполнить запрошенные поля.15803. Увеличить внутренний счётчик числа экспортов.15814. Установить `view->obj` в *экспортёр* и увеличить `view->obj`.15825. Вернуть `0`.15831584Если *экспортёр* является частью цепочки или дерева поставщиков буферов, можно использовать две основные схемы:15851586- Повторный экспорт: каждый элемент дерева выступает в роли экспортирующего объекта и устанавливает `view->obj` в новую ссылку на себя.1587- Перенаправление: запрос буфера перенаправляется корневому объекту дерева. Здесь `view->obj` будет новой ссылкой на корневой объект.15881589Отдельные поля *представления* описаны в разделе [Структура буфера](https://python-all.ru/3.10/c-api/buffer.html#buffer-structure), правила, как экспортёр должен реагировать на конкретные запросы – в разделе [Типы запросов буфера](https://python-all.ru/3.10/c-api/buffer.html#buffer-request-types).15901591Вся память, на которую указывает структура [`Py_buffer`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer), принадлежит экспортёру и должна оставаться действительной, пока есть хотя бы один потребитель. [`format`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer.format), [`shape`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer.shape), [`strides`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer.strides), [`suboffsets`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer.suboffsets) и [`internal`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer.internal) доступны потребителю только для чтения.15921593[`PyBuffer_FillInfo()`](https://python-all.ru/3.10/c-api/buffer.html#c.PyBuffer_FillInfo) предоставляет простой способ предоставления простого байтового буфера, корректно обрабатывая все типы запросов.15941595[`PyObject_GetBuffer()`](https://python-all.ru/3.10/c-api/buffer.html#c.PyObject_GetBuffer) – это интерфейс для потребителя, который оборачивает эту функцию.15961597#### `releasebufferproc PyBufferProcs.bf_releasebuffer`15981599Сигнатура этой функции:16001601```c1602void (PyObject *exporter, Py_buffer *view);1603```16041605Обрабатывает запрос на освобождение ресурсов буфера. Если никакие ресурсы освобождать не нужно, [`PyBufferProcs.bf_releasebuffer`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyBufferProcs.bf_releasebuffer) может быть `NULL`. В противном случае стандартная реализация этой функции выполнит следующие необязательные шаги:160616071. Уменьшить внутренний счётчик числа экспортов.16082. Если счётчик равен `0`, освободить всю память, связанную с *представлением*.16091610Экспортёр ОБЯЗАН использовать поле [`internal`](https://python-all.ru/3.10/c-api/buffer.html#c.Py_buffer.internal) для отслеживания ресурсов, специфичных для буфера. Гарантируется, что это поле остаётся постоянным, в то время как потребитель МОЖЕТ передавать копию исходного буфера в качестве аргумента *view*.16111612Эта функция НЕ ДОЛЖНА уменьшать `view->obj`, так как это делается автоматически в [`PyBuffer_Release()`](https://python-all.ru/3.10/c-api/buffer.html#c.PyBuffer_Release) (такая схема полезна для разрыва циклических ссылок).16131614[`PyBuffer_Release()`](https://python-all.ru/3.10/c-api/buffer.html#c.PyBuffer_Release) – это интерфейс для потребителя, который оборачивает эту функцию.16151616# Асинхронные структуры объектов16171618Новое в версии 3.5.16191620#### `type PyAsyncMethods`16211622Эта структура содержит указатели на функции, необходимые для реализации объектов [ожидаемый объект](https://python-all.ru/3.10/glossary.html#term-awaitable) и [асинхронный итератор](https://python-all.ru/3.10/glossary.html#term-asynchronous-iterator).16231624Вот определение структуры:16251626```c1627typedef struct {1628 unaryfunc am_await;1629 unaryfunc am_aiter;1630 unaryfunc am_anext;1631 sendfunc am_send;1632} PyAsyncMethods;1633```16341635#### `unaryfunc PyAsyncMethods.am_await`16361637Сигнатура этой функции:16381639```c1640PyObject *am_await(PyObject *self);1641```16421643Возвращаемый объект должен быть [итератором](https://python-all.ru/3.10/glossary.html#term-iterator), т.е. [`PyIter_Check()`](https://python-all.ru/3.10/c-api/iter.html#c.PyIter_Check) должен возвращать `1` для него.16441645Этот слот может быть установлен в `NULL`, если объект не является [ожидаемым объектом](https://python-all.ru/3.10/glossary.html#term-awaitable).16461647#### `unaryfunc PyAsyncMethods.am_aiter`16481649Сигнатура этой функции:16501651```c1652PyObject *am_aiter(PyObject *self);1653```16541655Должен возвращать объект [асинхронный итератор](https://python-all.ru/3.10/glossary.html#term-asynchronous-iterator). Подробнее см. `__anext__()`.16561657Этот слот может быть установлен в `NULL`, если объект не реализует протокол асинхронной итерации.16581659#### `unaryfunc PyAsyncMethods.am_anext`16601661Сигнатура этой функции:16621663```c1664PyObject *am_anext(PyObject *self);1665```16661667Должен возвращать объект [ожидаемый объект](https://python-all.ru/3.10/glossary.html#term-awaitable). Подробности см. в `__anext__()`. Этот слот может быть установлен в `NULL`.16681669#### `sendfunc PyAsyncMethods.am_send`16701671Сигнатура этой функции:16721673```c1674PySendResult am_send(PyObject *self, PyObject *arg, PyObject **result);1675```16761677Подробнее см. [`PyIter_Send()`](https://python-all.ru/3.10/c-api/iter.html#c.PyIter_Send). Этот слот может быть установлен в `NULL`.16781679Новое в версии 3.10.16801681# Определения типов слотов16821683#### `typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)`16841685*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*16861687Назначение этой функции – разделить выделение памяти и её инициализацию. Она должна возвращать указатель на блок памяти достаточной длины для экземпляра, с подходящим выравниванием и обнулённый, но с `ob_refcnt`, установленным в `1`, и `ob_type`, установленным в аргумент типа. Если [`tp_itemsize`](https://python-all.ru/3.10/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.10/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).16881689Эта функция не должна выполнять никакой другой инициализации экземпляра, включая выделение дополнительной памяти; это должно выполнять [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new).16901691#### `typedef void (*destructor)(PyObject*)`16921693*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*16941695#### `typedef void (*freefunc)(void*)`16961697См. [`tp_free`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_free).16981699#### `typedef PyObject *(*newfunc)(PyObject*, PyObject*, PyObject*)`17001701*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17021703См. [`tp_new`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_new).17041705#### `typedef int (*initproc)(PyObject*, PyObject*, PyObject*)`17061707*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17081709См. [`tp_init`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_init).17101711#### `typedef PyObject *(*reprfunc)(PyObject*)`17121713*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17141715См. [`tp_repr`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_repr).17161717#### `typedef PyObject *(*getattrfunc)(PyObject *self, char *attr)`17181719*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17201721Возвращает значение именованного атрибута для объекта.17221723#### `typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value)`17241725*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17261727Устанавливает значение именованного атрибута для объекта. Аргумент value устанавливается в `NULL` для удаления атрибута.17281729#### `typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr)`17301731*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17321733Возвращает значение именованного атрибута для объекта.17341735См. [`tp_getattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_getattro).17361737#### `typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)`17381739*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17401741Устанавливает значение именованного атрибута для объекта. Аргумент value устанавливается в `NULL` для удаления атрибута.17421743См. [`tp_setattro`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_setattro).17441745#### `typedef PyObject *(*descrgetfunc)(PyObject*, PyObject*, PyObject*)`17461747*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17481749См. [`tp_descr_get`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_descr_get).17501751#### `typedef int (*descrsetfunc)(PyObject*, PyObject*, PyObject*)`17521753*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17541755См. [`tp_descr_set`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_descr_set).17561757#### `typedef Py_hash_t (*hashfunc)(PyObject*)`17581759*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17601761См. [`tp_hash`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_hash).17621763#### `typedef PyObject *(*richcmpfunc)(PyObject*, PyObject*, int)`17641765*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17661767См. [`tp_richcompare`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_richcompare).17681769#### `typedef PyObject *(*getiterfunc)(PyObject*)`17701771*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17721773См. [`tp_iter`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_iter).17741775#### `typedef PyObject *(*iternextfunc)(PyObject*)`17761777*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17781779См. [`tp_iternext`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyTypeObject.tp_iternext).17801781#### `typedef Py_ssize_t (*lenfunc)(PyObject*)`17821783*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17841785#### `typedef int (*getbufferproc)(PyObject*, Py_buffer*, int)`17861787#### `typedef void (*releasebufferproc)(PyObject*, Py_buffer*)`17881789#### `typedef PyObject *(*unaryfunc)(PyObject*)`17901791*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17921793#### `typedef PyObject *(*binaryfunc)(PyObject*, PyObject*)`17941795*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*17961797#### `typedef PySendResult (*sendfunc)(PyObject*, PyObject*, PyObject**)`17981799См. [`am_send`](https://python-all.ru/3.10/c-api/typeobj.html#c.PyAsyncMethods.am_send).18001801#### `typedef PyObject *(*ternaryfunc)(PyObject*, PyObject*, PyObject*)`18021803*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*18041805#### `typedef PyObject *(*ssizeargfunc)(PyObject*, Py_ssize_t)`18061807*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*18081809#### `typedef int (*ssizeobjargproc)(PyObject*, Py_ssize_t, PyObject*)`18101811*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*18121813#### `typedef int (*objobjproc)(PyObject*, PyObject*)`18141815*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*18161817#### `typedef int (*objobjargproc)(PyObject*, PyObject*, PyObject*)`18181819*Часть [Stable ABI](https://python-all.ru/3.10/c-api/stable.html#stable).*18201821# Примеры18221823Ниже приведены простые примеры определений типов Python. Они включают распространённые варианты использования, с которыми можно столкнуться. Некоторые демонстрируют сложные граничные случаи. За дополнительными примерами, практической информацией и учебным пособием обращайтесь к [Defining Extension Types: Tutorial](https://python-all.ru/3.10/extending/newtypes_tutorial.html#defining-new-types) и [Defining Extension Types: Assorted Topics](https://python-all.ru/3.10/extending/newtypes.html#new-types-topics).18241825Базовый [статический тип](https://python-all.ru/3.10/c-api/typeobj.html#static-types):18261827```c1828typedef struct {1829 PyObject_HEAD1830 const char *data;1831} MyObject;18321833static PyTypeObject MyObject_Type = {1834 PyVarObject_HEAD_INIT(NULL, 0)1835 .tp_name = "mymod.MyObject",1836 .tp_basicsize = sizeof(MyObject),1837 .tp_doc = PyDoc_STR("My objects"),1838 .tp_new = myobj_new,1839 .tp_dealloc = (destructor)myobj_dealloc,1840 .tp_repr = (reprfunc)myobj_repr,1841};1842```18431844Также можно встретить старый код (особенно в кодовой базе CPython) с более многословным инициализатором:18451846```c1847static PyTypeObject MyObject_Type = {1848 PyVarObject_HEAD_INIT(NULL, 0)1849 "mymod.MyObject", /* tp_name */1850 sizeof(MyObject), /* tp_basicsize */1851 0, /* tp_itemsize */1852 (destructor)myobj_dealloc, /* tp_dealloc */1853 0, /* tp_vectorcall_offset */1854 0, /* tp_getattr */1855 0, /* tp_setattr */1856 0, /* tp_as_async */1857 (reprfunc)myobj_repr, /* tp_repr */1858 0, /* tp_as_number */1859 0, /* tp_as_sequence */1860 0, /* tp_as_mapping */1861 0, /* tp_hash */1862 0, /* tp_call */1863 0, /* tp_str */1864 0, /* tp_getattro */1865 0, /* tp_setattro */1866 0, /* tp_as_buffer */1867 0, /* tp_flags */1868 PyDoc_STR("My objects"), /* tp_doc */1869 0, /* tp_traverse */1870 0, /* tp_clear */1871 0, /* tp_richcompare */1872 0, /* tp_weaklistoffset */1873 0, /* tp_iter */1874 0, /* tp_iternext */1875 0, /* tp_methods */1876 0, /* tp_members */1877 0, /* tp_getset */1878 0, /* tp_base */1879 0, /* tp_dict */1880 0, /* tp_descr_get */1881 0, /* tp_descr_set */1882 0, /* tp_dictoffset */1883 0, /* tp_init */1884 0, /* tp_alloc */1885 myobj_new, /* tp_new */1886};1887```18881889Тип, поддерживающий слабые ссылки, словари экземпляров и хеширование:18901891```c1892typedef struct {1893 PyObject_HEAD1894 const char *data;1895 PyObject *inst_dict;1896 PyObject *weakreflist;1897} MyObject;18981899static PyTypeObject MyObject_Type = {1900 PyVarObject_HEAD_INIT(NULL, 0)1901 .tp_name = "mymod.MyObject",1902 .tp_basicsize = sizeof(MyObject),1903 .tp_doc = PyDoc_STR("My objects"),1904 .tp_weaklistoffset = offsetof(MyObject, weakreflist),1905 .tp_dictoffset = offsetof(MyObject, inst_dict),1906 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,1907 .tp_new = myobj_new,1908 .tp_traverse = (traverseproc)myobj_traverse,1909 .tp_clear = (inquiry)myobj_clear,1910 .tp_alloc = PyType_GenericNew,1911 .tp_dealloc = (destructor)myobj_dealloc,1912 .tp_repr = (reprfunc)myobj_repr,1913 .tp_hash = (hashfunc)myobj_hash,1914 .tp_richcompare = PyBaseObject_Type.tp_richcompare,1915};1916```19171918Подкласс str, который нельзя наследовать и который нельзя вызывать для создания экземпляров (например, используется отдельная фабричная функция) с помощью флага `Py_TPFLAGS_DISALLOW_INSTANTIATION`:19191920```c1921typedef struct {1922 PyUnicodeObject raw;1923 char *extra;1924} MyStr;19251926static PyTypeObject MyStr_Type = {1927 PyVarObject_HEAD_INIT(NULL, 0)1928 .tp_name = "mymod.MyStr",1929 .tp_basicsize = sizeof(MyStr),1930 .tp_base = NULL, // устанавливается в &PyUnicode_Type при инициализации модуля1931 .tp_doc = PyDoc_STR("my custom str"),1932 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,1933 .tp_repr = (reprfunc)myobj_repr,1934};1935```19361937Простейший [статический тип](https://python-all.ru/3.10/c-api/typeobj.html#static-types) с экземплярами фиксированной длины:19381939```c1940typedef struct {1941 PyObject_HEAD1942} MyObject;19431944static PyTypeObject MyObject_Type = {1945 PyVarObject_HEAD_INIT(NULL, 0)1946 .tp_name = "mymod.MyObject",1947};1948```19491950Простейший [статический тип](https://python-all.ru/3.10/c-api/typeobj.html#static-types) с экземплярами переменной длины:19511952```c1953typedef struct {1954 PyObject_VAR_HEAD1955 const char *data[1];1956} MyObject;19571958static PyTypeObject MyObject_Type = {1959 PyVarObject_HEAD_INIT(NULL, 0)1960 .tp_name = "mymod.MyObject",1961 .tp_basicsize = sizeof(MyObject) - sizeof(char *),1962 .tp_itemsize = sizeof(char *),1963};1964```1965