structures.md
1> **Источник:** https://python-all.ru/2.7/c-api/structures.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Структуры общих объектов89При определении типов объектов Python используется большое количество структур. В данном разделе описываются эти структуры и принципы их использования.1011Все объекты Python имеют в начале своего представления в памяти небольшое число общих полей. Эти поля описываются типами [`PyObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) и [`PyVarObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyVarObject), которые, в свою очередь, определяются через раскрытие некоторых макросов, используемых (прямо или косвенно) при определении всех остальных объектов Python.1213**`PyObject`**1415Все типы объектов являются расширениями этого типа. Это тип, который содержит информацию, необходимую Python для того, чтобы рассматривать указатель на объект как объект. В обычной «релизной» сборке он содержит только счетчик ссылок объекта и указатель на соответствующий объект типа. Он соответствует полям, определяемым развертыванием макроса `PyObject_HEAD`.1617**`PyVarObject`**1819Это расширение [`PyObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject), добавляющее поле `ob_size`. Используется только для объектов, имеющих некоторое понятие *длины*. Этот тип редко встречается в Python/C API. Он соответствует полям, определяемым развертыванием макроса `PyObject_VAR_HEAD`.2021Эти макросы используются в определении [`PyObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) и [`PyVarObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyVarObject):2223**`PyObject_HEAD`**2425Это макрос, который разворачивается в объявления полей типа [`PyObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject); он используется при объявлении новых типов, представляющих объекты без изменяемой длины. Конкретные поля, в которые он разворачивается, зависят от определения `Py_TRACE_REFS`. По умолчанию этот макрос не определен, и [`PyObject_HEAD`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject_HEAD) разворачивается в:2627```c28Py_ssize_t ob_refcnt;29PyTypeObject *ob_type;30```3132Когда `Py_TRACE_REFS` определен, он разворачивается в:3334```c35PyObject *_ob_next, *_ob_prev;36Py_ssize_t ob_refcnt;37PyTypeObject *ob_type;38```3940**`PyObject_VAR_HEAD`**4142Это макрос, который разворачивается в объявления полей типа [`PyVarObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyVarObject); он используется при объявлении новых типов, представляющих объекты с длиной, которая меняется от экземпляра к экземпляру. Этот макрос всегда разворачивается в:4344```c45PyObject_HEAD46Py_ssize_t ob_size;47```4849Обратите внимание, что [`PyObject_HEAD`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject_HEAD) является частью развертывания, и его собственное развертывание зависит от определения `Py_TRACE_REFS`.5051**`Py_TYPE`(o)**5253Этот макрос используется для доступа к полю `ob_type` объекта Python. Он раскрывается в:5455```c56(((PyObject*)(o))->ob_type)57```5859Новое в версии 2.6.6061**`Py_REFCNT`(o)**6263Этот макрос используется для доступа к полю `ob_refcnt` объекта Python. Он раскрывается в:6465```c66(((PyObject*)(o))->ob_refcnt)67```6869Новое в версии 2.6.7071**`Py_SIZE`(o)**7273Этот макрос используется для доступа к полю `ob_size` объекта Python. Он раскрывается в:7475```c76(((PyVarObject*)(o))->ob_size)77```7879Новое в версии 2.6.8081**`PyObject_HEAD_INIT`(type)**8283Это макрос, который раскрывается в значения инициализации для нового типа [`PyObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject). Этот макрос раскрывается в:8485```c86_PyObject_EXTRA_INIT871, type,88```8990**`PyVarObject_HEAD_INIT`(type, size)**9192Это макрос, который разворачивается в значения инициализации для нового типа [`PyVarObject`](https://python-all.ru/2.7/c-api/structures.html#c.PyVarObject), включая поле `ob_size`. Этот макрос разворачивается в:9394```c95_PyObject_EXTRA_INIT961, type, size,97```9899**`PyCFunction`**100101Тип функций, используемых для реализации большинства вызываемых объектов Python в C. Функции этого типа принимают два параметра [`PyObject*`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) и возвращают одно такое значение. Если возвращаемое значение равно *NULL*, то было установлено исключение. Если не *NULL*, возвращаемое значение интерпретируется как возвращаемое значение функции, доступное в Python. Функция должна возвращать новую ссылку.102103**`PyMethodDef`**104105Структура, используемая для описания метода типа-расширения. Эта структура имеет четыре поля:106107| Поле | Тип C | Значение |108| --- | --- | --- |109| `ml_name` | char \* | имя метода |110| `ml_meth` | PyCFunction | указатель на реализацию на C |111| `ml_flags` | int | биты флагов, указывающие, как должен быть построен вызов |112| `ml_doc` | char \* | указывает на содержимое докстринга |113114`ml_meth` – это указатель на функцию C. Функции могут быть разных типов, но они всегда возвращают [`PyObject*`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject). Если функция не является [`PyCFunction`](https://python-all.ru/2.7/c-api/structures.html#c.PyCFunction), компилятор потребует приведения в таблице методов. Хотя [`PyCFunction`](https://python-all.ru/2.7/c-api/structures.html#c.PyCFunction) определяет первый параметр как [`PyObject*`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject), обычно реализация метода использует конкретный тип C объекта *self*.115116Поле `ml_flags` является битовым полем, которое может содержать следующие флаги. Отдельные флаги указывают либо на соглашение о вызове, либо на соглашение о привязке. Из флагов соглашения о вызове можно комбинировать только [`METH_VARARGS`](https://python-all.ru/2.7/c-api/structures.html#METH_VARARGS) и [`METH_KEYWORDS`](https://python-all.ru/2.7/c-api/structures.html#METH_KEYWORDS). Любой из флагов соглашения о вызове можно комбинировать с флагом привязки.117118#### `METH_VARARGS`119120Это типичное соглашение о вызове, при котором методы имеют тип [`PyCFunction`](https://python-all.ru/2.7/c-api/structures.html#c.PyCFunction). Функция ожидает два значения [`PyObject*`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject). Первое – это объект *self* для методов; для функций модуля это объект модуля. Второй параметр (часто называемый *args*) – это объект-кортеж, представляющий все аргументы. Этот параметр обычно обрабатывается с помощью [`PyArg_ParseTuple()`](https://python-all.ru/2.7/c-api/arg.html#c.PyArg_ParseTuple) или [`PyArg_UnpackTuple()`](https://python-all.ru/2.7/c-api/arg.html#c.PyArg_UnpackTuple).121122#### `METH_KEYWORDS`123124Методы с этими флагами должны быть типа `PyCFunctionWithKeywords`. Функция ожидает три параметра: *self*, *args* и словарь всех именованных аргументов. Этот флаг обычно комбинируется с [`METH_VARARGS`](https://python-all.ru/2.7/c-api/structures.html#METH_VARARGS), а параметры обычно обрабатываются с помощью [`PyArg_ParseTupleAndKeywords()`](https://python-all.ru/2.7/c-api/arg.html#c.PyArg_ParseTupleAndKeywords).125126#### `METH_NOARGS`127128Методы без параметров не должны проверять, переданы ли аргументы, если они указаны с флагом [`METH_NOARGS`](https://python-all.ru/2.7/c-api/structures.html#METH_NOARGS). Они должны быть типа [`PyCFunction`](https://python-all.ru/2.7/c-api/structures.html#c.PyCFunction). Первый параметр обычно называется `self` и содержит ссылку на модуль или экземпляр объекта. Во всех случаях второй параметр будет равен *NULL*.129130#### `METH_O`131132Методы с одним аргументом-объектом могут быть перечислены с помощью флага [`METH_O`](https://python-all.ru/2.7/c-api/structures.html#METH_O) вместо вызова [`PyArg_ParseTuple()`](https://python-all.ru/2.7/c-api/arg.html#c.PyArg_ParseTuple) с аргументом `"O"`. Они имеют тип [`PyCFunction`](https://python-all.ru/2.7/c-api/structures.html#c.PyCFunction), с параметром *self* и параметром [`PyObject*`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject), представляющим единственный аргумент.133134#### `METH_OLDARGS`135136Это соглашение о вызове устарело. Метод должен быть типа [`PyCFunction`](https://python-all.ru/2.7/c-api/structures.html#c.PyCFunction). Второй аргумент равен *NULL*, если аргументы не переданы; одному объекту, если передан ровно один аргумент; и кортежу объектов, если передано более одного аргумента. Функция, использующая это соглашение, не может различить вызов с несколькими аргументами и вызов с кортежем в качестве единственного аргумента.137138Эти две константы не используются для указания соглашения о вызовах, а для привязки при использовании с методами классов. Они не могут использоваться для функций, определённых для модулей. Для любого данного метода может быть установлен не более чем один из этих флагов.139140#### `METH_CLASS`141142Метод получит объект типа в качестве первого параметра, а не экземпляр типа. Это используется для создания *методов класса*, аналогично тому, что создаётся при использовании [`classmethod()`](https://python-all.ru/2.7/library/functions.html#classmethod) встроенной функции.143144Новое в версии 2.3.145146#### `METH_STATIC`147148Методу будет передан *NULL* в качестве первого параметра вместо экземпляра типа. Это используется для создания *статических методов*, аналогичных тому, что создаётся при использовании встроенной функции [`staticmethod()`](https://python-all.ru/2.7/library/functions.html#staticmethod).149150Новое в версии 2.3.151152Ещё одна константа управляет тем, загружается ли метод вместо другого определения с тем же именем метода.153154#### `METH_COEXIST`155156Метод будет загружен вместо существующих определений. Без *METH\_COEXIST* по умолчанию повторяющиеся определения пропускаются. Поскольку обёртки слотов загружаются до таблицы методов, наличие слота *sq\_contains*, например, приведёт к созданию обёрнутого метода с именем [`__contains__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__contains__) и предотвратит загрузку соответствующего PyCFunction с тем же именем. При установленном флаге PyCFunction будет загружен вместо объекта-обёртки и будет сосуществовать со слотом. Это полезно, поскольку вызовы PyCFunctions оптимизированы лучше, чем вызовы объектов-обёрток.157158Новое в версии 2.4.159160**`PyMemberDef`**161162Структура, описывающая атрибут типа, который соответствует члену C-структуры. Её поля:163164| Поле | Тип C | Значение |165| --- | --- | --- |166| `name` | char \* | имя члена |167| `type` | int | тип члена в C-структуре |168| `offset` | Py\_ssize\_t | смещение в байтах, по которому член расположен в объектной структуре типа |169| `flags` | int | биты флага, указывающие, должно ли поле быть только для чтения или доступным для записи |170| `doc` | char \* | указывает на содержимое докстринга |171172`type` может быть одним из многих макросов `T_`, соответствующих различным C типам. При обращении к члену из Python он будет преобразован в эквивалентный тип Python.173174| Имя макроса | Тип C |175| --- | --- |176| T\_SHORT | short |177| T\_INT | int |178| T\_LONG | long |179| T\_FLOAT | float |180| T\_DOUBLE | double |181| T\_STRING | char \* |182| T\_OBJECT | PyObject \* |183| T\_OBJECT\_EX | PyObject \* |184| T\_CHAR | char |185| T\_BYTE | char |186| T\_UBYTE | беззнаковый char |187| T\_UINT | беззнаковый int |188| T\_USHORT | беззнаковый short |189| T\_ULONG | беззнаковый long |190| T\_BOOL | char |191| T\_LONGLONG | long long |192| T\_ULONGLONG | беззнаковый long long |193| T\_PYSSIZET | Py\_ssize\_t |194195`T_OBJECT` и `T_OBJECT_EX` различаются тем, что `T_OBJECT` возвращает `None`, если поле равно *NULL*, а `T_OBJECT_EX` возбуждает [`AttributeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.AttributeError). Старайтесь использовать `T_OBJECT_EX` вместо `T_OBJECT`, поскольку `T_OBJECT_EX` более корректно обрабатывает использование оператора [`del`](https://python-all.ru/2.7/reference/simple_stmts.html#del) для этого атрибута, чем `T_OBJECT`.196197`flags` может быть `0` для доступа на запись и чтение или `READONLY` для доступа только для чтения. Использование `T_STRING` для [`type`](https://python-all.ru/2.7/library/functions.html#type) подразумевает `READONLY`. Могут быть удалены только члены `T_OBJECT` и `T_OBJECT_EX`. (Они устанавливаются в *NULL*).198199**`PyGetSetDef`**200201Структура для определения доступа по типу свойства для типа. См. также описание слота [`PyTypeObject.tp_getset`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getset).202203| Поле | Тип C | Значение |204| --- | --- | --- |205| имя | char \* | имя атрибута |206| get | getter | C-функция для получения атрибута |207| множество | setter | необязательная C-функция для установки или удаления атрибута, если не указана, атрибут доступен только для чтения |208| doc | char \* | необязательная строка документации |209| closure | void \* | необязательный указатель на функцию, предоставляющий дополнительные данные для геттера и сеттера |210211Функция `get` принимает один параметр [`PyObject*`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) (экземпляр) и указатель на функцию (связанный `closure`):212213```c214typedef PyObject *(*getter)(PyObject *, void *);215```216217В случае успеха должна возвращать новую ссылку, или *NULL* с установленным исключением при неудаче.218219Функции `set` принимают два параметра [`PyObject*`](https://python-all.ru/2.7/c-api/structures.html#c.PyObject) (экземпляр и устанавливаемое значение) и указатель на функцию (связанный `closure`):220221```c222typedef int (*setter)(PyObject *, PyObject *, void *);223```224225Если атрибут должен быть удалён, второй параметр равен *NULL*. Должна возвращать `0` при успехе или `-1` с установленным исключением при неудаче.226227#### `PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name)`228229*Возвращаемое значение: новая ссылка.*230231Возвращает объект связанного метода для типа расширения, реализованного на C. Это может быть полезно при реализации обработчика [`tp_getattro`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattro) или [`tp_getattr`](https://python-all.ru/2.7/c-api/typeobj.html#c.PyTypeObject.tp_getattr), который не использует функцию [`PyObject_GenericGetAttr()`](https://python-all.ru/2.7/c-api/object.html#c.PyObject_GenericGetAttr).232