Общие структуры объектов

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

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

PyObject

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

PyVarObject

Расширение PyObject, добавляющее поле ob_size. Это используется только для объектов, которые имеют некоторое понятие length. Этот тип не часто появляется в API Python/C. Доступ к участникам должен осуществляться с помощью макросов 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 с сигнатурой METH_VARARGS | METH_KEYWORDS.

_PyCFunctionFast

Тип функций, используемых для реализации Python вызовов в C с сигнатурой METH_FASTCALL.

_PyCFunctionFastWithKeywords

Тип функций, используемых для реализации Python вызовов в C с сигнатурой METH_FASTCALL | METH_KEYWORDS.

PyMethodDef

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

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

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

Поле ml_flags является битовым полем, которое может содержать следующие флаги. Отдельные флаги обозначают либо соглашение о вызове, либо соглашение о биндинге.

Существует четыре основных соглашения о вызове позиционных аргументов, и два из них могут быть объединены с METH_KEYWORDS для поддержки тех же ключевых аргументов. Таким образом, существует в общей сложности 6 соглашений о вызове:

METH_VARARGS

Типичное соглашение о вызове, в котором методы имеют тип PyCFunction. Функция ожидает два PyObject* значения. Первый - это self объект для методов; для функций модуля - это объект модуля. Второй параметр (часто называемый args) представляет собой объект кортежа, представляющий все аргументы. Этот параметр обычно обрабатывается с использованием PyArg_ParseTuple() или PyArg_UnpackTuple().

METH_VARARGS | METH_KEYWORDS

Методы с этими флагами должны иметь тип PyCFunctionWithKeywords. Функция ожидает три параметра: self, args, kwargs где kwargs - словарь всех ключевых аргументов или, возможно, NULL при отсутствии ключевых аргументов. Параметры обычно обрабатываются с использованием PyArg_ParseTupleAndKeywords().

METH_FASTCALL

Соглашение быстрого вызова, поддерживающее только позиционные аргументы. Методы имеют тип _PyCFunctionFast. Первый параметр - self, второй - C-массив PyObject* значения указывающий аргументы, а третий - количество аргументов (длина массива).

Это не часть ограниченного API.

Добавлено в версии 3.7.

METH_FASTCALL | METH_KEYWORDS

Расширение METH_FASTCALL, поддерживающих также ключевой аргументы, с методами типа _PyCFunctionFastWithKeywords. Ключевые аргументы передаются так же, как и в протоколе vectorcall: существует дополнительный четвёртый параметр PyObject*, представляющий собой кортеж, представляющий имена ключевых аргументов или, возможно, NULL, если нет ключевых слов. После позиционных аргументов значений ключевых аргументов сохраняются в массиве args.

Это не часть ограниченного API.

Добавлено в версии 3.7.

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 const char * имя члена
type int тип члена в C структуре
offset Py_ssize_t смещение в байтах, в котором член расположен в структуре типа объекта
flags int биты флага, указывающие, должно ли поле быть доступным только для чтения или для записи
doc const char * указывает на содержимое докстринга

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

Имя макро C тип
T_SHORT short
T_INT int
T_LONG long
T_FLOAT float
T_DOUBLE double
T_STRING const 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_STRING данные интерпретируются как UTF-8. Удалить можно только T_OBJECT и T_OBJECT_EX члены. (Для них установлено значение NULL).

PyGetSetDef

Структура для определения типа доступа, подобного свойству. См. также описание слота PyTypeObject.tp_getset.

Поле C тип Смысл
name const char * имя атрибута
get getter C функция для получения атрибута
set setter необязательная C функция для установки или удаления атрибута, если пропущенный атрибут только для чтения
doc const char * опциональный докстринг
closure void * необязательный указатель функции, предоставляющий дополнительные данные для геттера и сеттера

Функция get принимает один параметр PyObject* (сущность) и указатель функции (соответствующий closure):

typedef PyObject *(*getter)(PyObject *, void *);

Он должен возвращать новую ссылку при успехе или NULL с установленным исключением при сбое.

set функции принимают два PyObject* параметра (сущность и значение, которые должны быть установлены) и указатель функции (соответствующий closure):

typedef int (*setter)(PyObject *, PyObject *, void *);

Если необходимо удалить атрибут, NULL второй параметр. Должен возвращать 0 в случае успеха или -1 с установленным исключением при сбое.