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

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

Типы базовых объектов и макросы

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

type PyObject
Part of the Limited API. (Only some members are part of the stable ABI.)

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

type PyVarObject
Part of the Limited API. (Only some members are part of the stable ABI.)

Это расширение 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 выше.

int Py_Is(const PyObject *x, const PyObject *y)
Part of the Stable ABI since version 3.10.

Проверяет, является ли объект x объектом y, аналогично x is y в Python.

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

int Py_IsNone(const PyObject *x)
Part of the Stable ABI since version 3.10.

Проверьте, является ли объект синглтоном None, то же самое, что x is None в Python.

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

int Py_IsTrue(const PyObject *x)
Part of the Stable ABI since version 3.10.

Проверьте, является ли объект синглтоном True, то же самое, что x is True в Python.

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

int Py_IsFalse(const PyObject *x)
Part of the Stable ABI since version 3.10.

Проверьте, является ли объект синглтоном False, то же самое, что x is False в Python.

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

PyTypeObject *Py_TYPE(const PyObject *o)

Получение типа объекта Python o.

Возвращает borrowed reference.

Для задания типа объекта необходимо использовать функцию Py_SET_TYPE().

int Py_IS_TYPE(PyObject *o, PyTypeObject *type)

Возвращает ненулевое значение, если тип объекта o равен type. В противном случае возвращается ноль. Эквивалентно: Py_TYPE(o) == type.

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

void Py_SET_TYPE(PyObject *o, PyTypeObject *type)

Установите тип объекта o в type.

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

Py_ssize_t Py_REFCNT(const PyObject *o)

Получить счетчик ссылок на объект Python o.

Изменено в версии 3.10: Py_REFCNT() заменена на встроенную статическую функцию. Используйте Py_SET_REFCNT() для установки количества ссылок на объект.

void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

Установите счетчик ссылок объекта o на refcnt.

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

Py_ssize_t Py_SIZE(const PyVarObject *o)

:c заменена на встроенную статическую функцию. Используйте :c для установки количества ссылок на объект.

Py_SET_SIZE() заменена на встроенную статическую функцию. Используйте :c для установки количества ссылок на объект.

void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)

Установите размер объекта o равным size.

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

PyObject_HEAD_INIT(type)

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

_PyObject_EXTRA_INIT
1, type,
PyVarObject_HEAD_INIT(type, size)

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

_PyObject_EXTRA_INIT
1, type, size,

Реализация функций и методов

type PyCFunction
Part of the Stable ABI.

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

Сигнатура функции следующая:

PyObject *PyCFunction(PyObject *self,
                      PyObject *args);
type PyCFunctionWithKeywords
Part of the Stable ABI.

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

PyObject *PyCFunctionWithKeywords(PyObject *self,
                                  PyObject *args,
                                  PyObject *kwargs);
type _PyCFunctionFast

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

PyObject *_PyCFunctionFast(PyObject *self,
                           PyObject *const *args,
                           Py_ssize_t nargs);
type _PyCFunctionFastWithKeywords

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

PyObject *_PyCFunctionFastWithKeywords(PyObject *self,
                                       PyObject *const *args,
                                       Py_ssize_t nargs,
                                       PyObject *kwnames);
type PyCMethod

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

PyObject *PyCMethod(PyObject *self,
                    PyTypeObject *defining_class,
                    PyObject *const *args,
                    Py_ssize_t nargs,
                    PyObject *kwnames)

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

type PyMethodDef
Part of the Stable ABI (including all members).

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

Поле

C Тип

Значение

ml_name

const char *

название метода

ml_meth

PyCFunction

указатель на реализацию C

ml_flags

int

биты флага, указывающие на то, как должен быть построен вызов

ml_doc

const char *

указывает на содержимое строки docstring

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

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

Существуют такие условные обозначения:

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*, указывающих на аргументы, а третьим параметром является количество аргументов (длина массива).

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

Изменено в версии 3.10: METH_FASTCALL теперь является частью стабильного ABI.

METH_FASTCALL | METH_KEYWORDS

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

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

METH_METHOD | METH_FASTCALL | METH_KEYWORDS

Расширение METH_FASTCALL | METH_KEYWORDS, поддерживающее определяющий класс, то есть класс, содержащий рассматриваемый метод. Определяющий класс может быть суперклассом Py_TYPE(self).

Метод должен иметь тип PyCMethod, такой же, как и для METH_FASTCALL | METH_KEYWORDS с аргументом defining_class, добавленным после self.

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

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 оптимизируются лучше, чем вызовы объектов-оберток.

Доступ к атрибутам типов расширения

type PyMemberDef
Part of the Stable ABI (including all members).

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

Поле

C Тип

Значение

name

const char *

имя участника

type

int

тип члена в структуре C

offset

Py_ssize_t

смещение в байтах, по которому член находится в объектной структуре типа

flags

int

биты флага, указывающие, должно ли поле быть доступно только для чтения или для записи

doc

const char *

указывает на содержимое строки docstring

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

Имя макроса

Тип C

T_SHORT

короткий

T_INT

int

T_LONG

длинный

T_FLOAT

float

T_DOUBLE

двойной

T_STRING

const char *

T_OBJECT

PyObject *

T_OBJECT_EX

PyObject *

T_CHAR

char

T_BYTE

char

T_UBYTE

беззнаковый символ

T_UINT

unsigned int

T_USHORT

беззнаковое сокращение

T_ULONG

беззнаковая длина

T_BOOL

char

T_LONGLONG

длинный длинный

T_ULONGLONG

беззнаковая длина 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).

Типы, выделенные из кучи (созданные с помощью PyType_FromSpec() или аналогично), PyMemberDef могут содержать определения для специальных членов __dictoffset__, __weaklistoffset__ и __vectorcalloffset__, соответствующих tp_dictoffset, tp_weaklistoffset и tp_vectorcall_offset в объектах типа. Они должны быть определены с помощью T_PYSSIZET и READONLY, например:

static PyMemberDef spam_type_members[] = {
    {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY},
    {NULL}  /* Sentinel */
};
PyObject *PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m)

Получить атрибут, принадлежащий объекту по адресу obj_addr. Атрибут описывается PyMemberDef m. Возвращает NULL при ошибке.

int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o)

Установить атрибут, принадлежащий объекту по адресу obj_addr, на объект o. Атрибут, который нужно установить, описывается PyMemberDef m. Возвращает 0 в случае успеха и отрицательное значение в случае неудачи.

type PyGetSetDef
Part of the Stable ABI (including all members).

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

Поле

C Тип

Значение

имя

const char *

имя атрибута

получить

getter

Функция C для получения атрибута

установить

сеттер

необязательная C-функция для установки или удаления атрибута, если опущена, атрибут доступен только для чтения

doc

const char *

необязательная строка документа

закрытие

void *

необязательный указатель функции, предоставляющий дополнительные данные для getter и setter

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

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

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

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

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

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

Вернуться на верх