Общие структуры объектов
Существует большое количество структур, используемых при определении типов объектов в Python. В этом разделе описаны эти структуры и как они используются.
Все объекты Python в конечном итоге разделяют небольшое количество полей в начале представления объекта в памяти. Они представлены типами PyObject и PyVarObject, которые, в свою очередь, определяются с помощью макросов, используемых, напрямую или косвенно, при определении всех остальных объектов Python.
-
PyObject -
Все типы объектов являются расширениями этого типа. Это тип, содержащий информацию, необходимую Python для обработки указателя на объект как на объект. В обычном релизном билде он содержит только счетчик ссылок объекта и указатель на соответствующий объект типа. Ничего фактически не объявляется как
PyObject, но каждый указатель на объект Python может быть приведён к типуPyObject*. Доступ к членам должен осуществляться с помощью макросовPy_REFCNTиPy_TYPE.
-
PyVarObject -
Это расширение
PyObject, добавляющее полеob_size. Оно используется только для объектов, имеющих понятие длины. Этот тип нечасто встречается в 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_nameconst char *
имя метода
ml_methPyCFunction
указатель на C реализацию
ml_flagsint
флаги, указывающие, как должна быть построена вызов
ml_docconst 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, второй — массив значений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 будет загружен вместо объекта-обёртки и будет сосуществовать со слотом. Это полезно, потому что вызовы 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).
-
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.8/c-api/structures.html