Spec-Zone.ru › Python 3.9

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

Существует большое количество структур, используемых при определении типов объектов в 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)
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_REFCNT(o)

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

(((PyObject*)(o))->ob_refcnt)
void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

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

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

Py_SIZE(o)

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

(((PyVarObject*)(o))->ob_size)
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,

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

PyCFunction

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

Подпись функции:

PyObject *PyCFunction(PyObject *self,
                      PyObject *args);
PyCFunctionWithKeywords

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

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

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

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

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

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

Тип функций, используемых для реализации вызываемых в Python объектов в 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.

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_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_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 загрузится вместо объекта обёртки и будет сосуществовать со слотом. Это полезно, потому что вызовы PyCFunction оптимизируются больше, чем вызовы объектов обёртки.

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

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).

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

PyGetSetDef

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

Поле

Тип C

Значение

name

const char *

имя атрибута

get

getter

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

set

setter

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

doc

const char *

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

closure

void *

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

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

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

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

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

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

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

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/c-api/structures.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API