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

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

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

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

PyObject
Все типы объектов являются расширениями этого типа. Это тип, содержащий информацию, необходимую Python для обработки указателя на объект как объекта. В обычной «релизной» сборке он содержит только счетчик ссылок объекта и указатель на соответствующий объект типа. Он соответствует полям, определяемым раскрытием макроса 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(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. Функция должна возвращать новую ссылку.
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_OLDARGS
Это соглашение о вызове устарело. Метод должен быть типа PyCFunction. Второй аргумент равен NULL, если аргументы не переданы, одному объекту, если передан ровно один аргумент, и кортежу объектов, если передано более одного аргумента. Функция, использующая это соглашение, не может различить вызов с несколькими аргументами и вызов с единственным аргументом-кортежем.

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

METH_CLASS

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

Новое в версии 2.3.

METH_STATIC

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

Новое в версии 2.3.

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

METH_COEXIST

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

Новое в версии 2.4.

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 беззнаковый 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. Рекомендуется использовать T_OBJECT_EX вместо T_OBJECT, так как T_OBJECT_EX корректнее обрабатывает применение оператора del к этому атрибуту, чем T_OBJECT.

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

PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name)
Возвращаемое значение: новая ссылка.

Возвращает объект привязанного метода для типа-расширения, реализованного на C. Это может быть полезно при реализации обработчика tp_getattro или tp_getattr, который не использует функцию PyObject_GenericGetAttr().