Структуры общих объектов¶Common Object Structures
При определении типов объектов Python используется большое количество структур. В данном разделе описываются эти структуры и принципы их использования.
Все объекты Python в конечном счёте имеют несколько общих полей в начале представления объекта в памяти. Они представлены типами PyObject и PyVarObject, которые, в свою очередь, определяются через раскрытие некоторых макросов, также используемых (напрямую или косвенно) в определении всех остальных объектов Python.
- PyObject¶
Все типы объектов являются расширениями этого типа. Это тип, содержащий информацию, необходимую Python для обработки указателя на объект как объекта. В обычной «релизной» сборке он содержит только счетчик ссылок объекта и указатель на соответствующий объект типа. Он соответствует полям, определяемым раскрытием макроса PyObject_HEAD.
- PyVarObject¶
Это расширение PyObject, добавляющее поле ob_size. Оно используется только для объектов, имеющих некоторое понятие длины. Этот тип нечасто встречается в Python/C API. Он соответствует полям, определяемым раскрытием макроса PyObject_VAR_HEAD.
Эти макросы используются в определении PyObject и PyVarObject:
- PyObject_HEAD¶
Это макрос, который раскрывается в объявления полей типа PyObject; он используется при объявлении новых типов, представляющих объекты без изменяемой длины. Конкретные поля, в которые он раскрывается, зависят от определения Py_TRACE_REFS. По умолчанию этот макрос не определен, и PyObject_HEAD раскрывается в:
Py_ssize_t ob_refcnt; PyTypeObject *ob_type;
Когда Py_TRACE_REFS определен, он раскрывается в:
PyObject *_ob_next, *_ob_prev; Py_ssize_t ob_refcnt; PyTypeObject *ob_type;
- PyObject_VAR_HEAD¶
Это макрос, который раскрывается в объявления полей типа PyVarObject; он используется при объявлении новых типов, представляющих объекты с длиной, которая меняется от экземпляра к экземпляру. Этот макрос всегда раскрывается в:
PyObject_HEAD Py_ssize_t ob_size;
Обратите внимание, что PyObject_HEAD является частью раскрытия, и его собственное раскрытие зависит от определения Py_TRACE_REFS.
- 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, которые принимают именованные аргументы: они принимают три параметра PyObject* и возвращают одно такое значение. См. PyCFunction выше для описания возвращаемого значения.
- PyMethodDef¶
Структура, используемая для описания метода типа-расширения. Эта структура имеет четыре поля:
Поле Тип C Значение ml_name char * имя метода ml_meth PyCFunction указатель на реализацию на C ml_flags int биты флагов, указывающие, как должен быть построен вызов ml_doc char * указывает на содержимое докстринга
Поле ml_meth – это указатель на функцию C. Функции могут быть разных типов, но они всегда возвращают PyObject*. Если функция не является PyCFunction, компилятор потребует приведения типа в таблице методов. Хотя PyCFunction определяет первый параметр как PyObject*, часто реализация метода использует конкретный C-тип объекта self.
Поле ml_flags – это битовое поле, которое может содержать следующие флаги. Отдельные флаги указывают либо соглашение о вызове, либо соглашение о связывании. Из флагов соглашения о вызове можно комбинировать только METH_VARARGS и METH_KEYWORDS (но обратите внимание, что METH_KEYWORDS сам по себе эквивалентен METH_VARARGS | METH_KEYWORDS). Любой флаг соглашения о вызове можно комбинировать с флагом связывания.
- METH_VARARGS¶
Это стандартное соглашение о вызове, при котором методы имеют тип PyCFunction. Функция ожидает два значения PyObject*. Первое – это объект self для методов; для модульных функций это объект модуля. Второй параметр (часто называемый args) представляет собой кортеж, содержащий все аргументы. Этот параметр обычно обрабатывается с помощью PyArg_ParseTuple() или PyArg_UnpackTuple().
- METH_KEYWORDS¶
Методы с этими флагами должны иметь тип PyCFunctionWithKeywords. Функция ожидает три параметра: self, args и словарь всех именованных аргументов. Этот флаг обычно комбинируется с METH_VARARGS, и параметры обычно обрабатываются с помощью PyArg_ParseTupleAndKeywords().
- 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 char * имя члена type int тип члена в C-структуре offset Py_ssize_t смещение в байтах, по которому член расположен в объектной структуре типа flags int биты флага, указывающие, должно ли поле быть только для чтения или доступным для записи doc char * указывает на содержимое докстринга Поле type может быть одним из многих макросов T_, соответствующих различным типам C. При обращении к элементу из Python он будет преобразован в соответствующий тип Python.
Имя макроса Тип C T_SHORT short T_INT int T_LONG long T_FLOAT float T_DOUBLE double T_STRING 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_OBJECT и T_OBJECT_EX могут быть удалены. (Они устанавливаются в NULL).