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

Структуры общих объектовCommon Object Structures

При определении типов объектов Python используется большое количество структур. В данном разделе описываются эти структуры и принципы их использования.

Все объекты Python в конечном итоге имеют небольшое количество общих полей в начале своего представления в памяти. Они представлены типами PyObject и PyVarObject, которые, в свою очередь, определяются расширениями некоторых макросов, также используемых, прямо или косвенно, при определении всех остальных объектов Python.

PyObject
Все типы объектов являются расширениями этого типа. Это тип, содержащий информацию, необходимую Python для обработки указателя на объект как объекта. В обычной «release»-сборке он содержит только счетчик ссылок объекта и указатель на соответствующий объект типа. Он соответствует полям, определенным расширением макроса PyObject_HEAD.
PyVarObject
Это расширение PyObject, добавляющее поле ob_size. Оно используется только для объектов, имеющих понятие длины. Этот тип редко встречается в Python/C API. Он соответствует полям, определенным расширением макроса PyObject_VAR_HEAD.

Эти макросы используются в определении PyObject и PyVarObject:

PyObject_HEAD

Это макрос, который разворачивается в объявления полей типа PyObject; он используется при объявлении новых типов, представляющих объекты без изменяемой длины. Конкретные поля, в которые он разворачивается, зависят от определения Py_TRACE_REFS. По умолчанию этот макрос не определен, и PyObject_HEAD разворачивается в:

Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;

Когда Py_TRACE_REFS определен, он раскрывается в:

PyObject *_ob_next, *_ob_prev;
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;
PyObject_VAR_HEAD

Это макрос, который разворачивается в объявления полей типа PyVarObject; он используется при объявлении новых типов, представляющих объекты с длиной, меняющейся от экземпляра к экземпляру. Этот макрос всегда разворачивается в:

PyObject_HEAD
Py_ssize_t ob_size;

Обратите внимание, что PyObject_HEAD является частью раскрытия, и его собственное раскрытие зависит от определения Py_TRACE_REFS.

PyObject_HEAD_INIT
PyCFunction
Тип функций, используемых для реализации большинства вызываемых объектов Python на C. Функции этого типа принимают два параметра PyObject* и возвращают одно такое значение. Если возвращаемое значение равно NULL, должно быть установлено исключение. Если не NULL, возвращаемое значение интерпретируется как возвращаемое значение функции, представленное в Python. Функция должна возвращать новую ссылку.
PyCFunctionWithKeywords
Тип функций, используемых для реализации вызываемых объектов Python на C, которые принимают именованные аргументы: они принимают три параметра PyObject* и возвращают одно такое значение. См. PyCFunction выше для описания возвращаемого значения.
PyMethodDef

Структура, используемая для описания метода типа-расширения. Эта структура имеет четыре поля:

Поле Тип C Значение
ml_name char * имя метода
ml_meth PyCFunction указатель на реализацию на C
ml_flags int биты флагов, указывающие, как должен быть построен вызов
ml_doc char * указывает на содержимое докстринга

Поле ml_meth – это указатель на функцию C. Функции могут быть разных типов, но они всегда возвращают PyObject*. Если функция не является PyCFunction, компилятор потребует приведения типа в таблице методов. Хотя PyCFunction определяет первый параметр как PyObject*, часто реализация метода использует конкретный C-тип объекта self.

Поле ml_flags – это битовое поле, которое может содержать следующие флаги. Отдельные флаги указывают либо соглашение о вызове, либо соглашение о связывании. Из флагов соглашения о вызове можно комбинировать только METH_VARARGS и METH_KEYWORDS (но обратите внимание, что METH_KEYWORDS сам по себе эквивалентен METH_VARARGS | METH_KEYWORDS). Любой флаг соглашения о вызове можно комбинировать с флагом связывания.

METH_VARARGS
Это типичное соглашение о вызове, когда методы имеют тип PyCFunction. Функция ожидает два значения PyObject*. Первое – это объект self для методов; для функций модуля оно равно значению, переданному в Py_InitModule4 (или NULL, если использовался Py_InitModule). Второй параметр (часто называемый args) – это объект-кортеж, представляющий все аргументы. Этот параметр обычно обрабатывается с помощью PyArg_ParseTuple или PyArg_UnpackTuple.
METH_KEYWORDS
Методы с этими флагами должны иметь тип PyCFunctionWithKeywords. Функция ожидает три параметра: self, args и словарь всех именованных аргументов. Этот флаг обычно комбинируется с METH_VARARGS, и параметры обычно обрабатываются с помощью PyArg_ParseTupleAndKeywords.
METH_NOARGS
Методам без параметров не нужно проверять, переданы ли аргументы, если они перечислены с флагом METH_NOARGS. Они должны иметь тип PyCFunction. При использовании с методами объектов первый параметр обычно называется self и содержит ссылку на экземпляр объекта. Во всех случаях второй параметр будет равен NULL.
METH_O
Методы с одним объектным аргументом могут быть перечислены с флагом METH_O вместо вызова PyArg_ParseTuple с аргументом "O". Они имеют тип PyCFunction, с параметром self и параметром PyObject*, представляющим единственный аргумент.

Эти две константы не используются для указания соглашения о вызовах, а для привязки при использовании с методами классов. Они не могут использоваться для функций, определённых для модулей. Для любого данного метода может быть установлен не более чем один из этих флагов.

METH_CLASS

Методу будет передан объект типа в качестве первого параметра, а не экземпляр типа. Это используется для создания методов класса, аналогично тому, что создается при использовании встроенной функции classmethod().

METH_STATIC

Методу будет передан NULL в качестве первого параметра, а не экземпляр типа. Это используется для создания статических методов, аналогично тому, что создается при использовании встроенной функции staticmethod().

Ещё одна константа управляет тем, загружается ли метод вместо другого определения с тем же именем метода.

METH_COEXIST
Метод будет загружен вместо существующих определений. Без METH_COEXIST по умолчанию повторные определения пропускаются. Поскольку обёртки слотов загружаются до таблицы методов, наличие слота sq_contains, например, приведёт к созданию обёрнутого метода с именем __contains__() и не позволит загрузить соответствующий PyCFunction с тем же именем. С установленным флагом PyCFunction будет загружен вместо объекта-обёртки и будет сосуществовать со слотом. Это полезно, так как вызовы PyCFunctions оптимизированы лучше, чем вызовы объектов-обёрток.
PyMemberDef

Структура, описывающая атрибут типа, который соответствует члену C-структуры. Её поля:

Поле Тип C Значение
name char * имя члена
type int тип члена в C-структуре
offset Py_ssize_t смещение в байтах, по которому член расположен в объектной структуре типа
flags int биты флага, указывающие, должно ли поле быть только для чтения или доступным для записи
doc char * указывает на содержимое докстринга

Поле type может быть одним из многих макросов T_, соответствующих различным типам C. При обращении к элементу из Python он будет преобразован в соответствующий тип Python.

Имя макроса Тип C
T_SHORT short
T_INT int
T_LONG long
T_FLOAT float
T_DOUBLE double
T_STRING char *
T_OBJECT PyObject *
T_OBJECT_EX PyObject *
T_CHAR char
T_BYTE char
T_UNBYTE беззнаковый char
T_UINT беззнаковый int
T_USHORT беззнаковый short
T_ULONG беззнаковый long
T_BOOL char
T_LONGLONG long long
T_ULONGLONG беззнаковый long long
T_PYSSIZET Py_ssize_t

T_OBJECT и T_OBJECT_EX различаются тем, что T_OBJECT возвращает None, если член равен NULL, а T_OBJECT_EX возбуждает исключение AttributeError.

flags может быть 0 для доступа на запись и чтение или READONLY для доступа только для чтения. Использование T_STRING для type неявно подразумевает READONLY. Только члены T_OBJECT и T_OBJECT_EX могут быть удалены. (Они устанавливаются в NULL).