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

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

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

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

PyObject

Все типы объектов являются расширениями этого типа. Это тип, который содержит информацию, необходимую Python для обработки указателя на объект как объекта. В обычной «релизной» сборке он содержит только счётчик ссылок объекта и указатель на соответствующий объект-тип. Ни один объект не объявляется как PyObject, но любой указатель на объект Python может быть приведён к PyObject*. Доступ к членам должен осуществляться с помощью макросов Py_REFCNT и Py_TYPE.

PyVarObject

Это расширение PyObject, добавляющее поле ob_size. Оно используется только для объектов, имеющих некоторое понятие длины. Этот тип редко встречается в Python/C API. Доступ к членам должен осуществляться с помощью макросов Py_REFCNT, Py_TYPE и Py_SIZE.

PyObject_HEAD

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

PyObject ob_base;

См. документацию PyObject выше.

PyObject_VAR_HEAD

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

PyVarObject ob_base;

См. документацию PyVarObject выше.

Py_TYPE(o)

Этот макрос используется для доступа к члену ob_type объекта Python. Он раскрывается в:

(((PyObject*)(o))->ob_type)
Py_REFCNT(o)

Этот макрос используется для доступа к члену ob_refcnt объекта Python. Он раскрывается в:

(((PyObject*)(o))->ob_refcnt)
Py_SIZE(o)

Этот макрос используется для доступа к члену ob_size объекта Python. Он раскрывается в:

(((PyVarObject*)(o))->ob_size)
PyObject_HEAD_INIT(type)

Это макрос, который раскрывается в значения инициализации для нового типа PyObject. Он раскрывается в:

_PyObject_EXTRA_INIT
1, type,
PyVarObject_HEAD_INIT(type, size)

Это макрос, который раскрывается в значения инициализации для нового типа PyVarObject, включая поле ob_size. Он раскрывается в:

_PyObject_EXTRA_INIT
1, type, size,
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 для методов; для модульных функций это объект модуля. Второй параметр (часто называемый 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_UBYTE unsigned char
T_UINT unsigned int
T_USHORT unsigned short
T_ULONG unsigned long
T_BOOL char
T_LONGLONG long long
T_ULONGLONG unsigned long long
T_PYSSIZET Py_ssize_t

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

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