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