Общие структуры объектов
Существует большое количество структур, используемых при определении типов объектов в 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_nameconst char *
имя метода
ml_methPyCFunction
указатель на реализацию C
ml_flagsint
флаги, указывающие, как должен быть построен вызов
ml_docconst 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
Значение
nameconst char *
имя члена
typeint
тип члена в C-структуре
offsetPy_ssize_t
смещение в байтах, где находится член в структуре объекта типа
flagsint
флаги, указывающие, является ли поле только для чтения или для записи
docconst 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. Атрибут описывается
PyMemberDefm. ВозвращаетNULLпри ошибке.
-
int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o) -
Установить атрибут, принадлежащий объекту по адресу obj_addr, на объект o. Атрибут, который нужно установить, описан в
PyMemberDefm. Возвращает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