Содержание страницы
Структуры объектов типа¶Type Object Structures
Пожалуй, одна из самых важных структур объектной системы Python – это структура, определяющая новый тип: структура PyTypeObject. Объекты типа можно обрабатывать с помощью любой из функций PyObject_* или PyType_*, но для большинства приложений Python они не представляют большого интереса. Эти объекты являются основой поведения объектов, поэтому они очень важны как для самого интерпретатора, так и для любых модулей расширения, реализующих новые типы.
Объекты типа довольно велики по сравнению с большинством стандартных типов. Причина такого размера в том, что каждый объект типа хранит большое количество значений, в основном указателей на функции C, каждый из которых реализует небольшую часть функциональности типа. Поля объекта типа подробно рассматриваются в этом разделе. Поля будут описаны в порядке их появления в структуре.
В дополнение к следующему краткому справочнику раздел Примеры даёт представление о значении и использовании PyTypeObject.
Краткий справочник¶Quick Reference
“tp slots”¶
PyTypeObject Slot [1] |
специальные методы/атрибуты |
Информация [2] |
||||
|---|---|---|---|---|---|---|
O |
T |
D |
I |
|||
<R> |
const char * |
name |
X |
X |
||
X |
X |
X |
||||
X |
X |
|||||
X |
X |
X |
||||
X |
X |
|||||
getattribute__, __getattr |
G |
|||||
setattr__, __delattr |
G |
|||||
% |
||||||
repr |
X |
X |
X |
|||
% |
||||||
% |
||||||
% |
||||||
hash |
X |
G |
||||
call |
X |
X |
||||
str |
X |
X |
||||
getattribute__, __getattr |
X |
X |
G |
|||
setattr__, __delattr |
X |
X |
G |
|||
% |
||||||
unsigned long |
X |
X |
? |
|||
const char * |
doc |
X |
X |
|||
X |
G |
|||||
X |
G |
|||||
lt__, __le__, __eq__, __ne__, __gt__, __ge |
X |
G |
||||
X |
? |
|||||
iter |
X |
|||||
next |
X |
|||||
|
X |
X |
||||
|
X |
|||||
|
X |
X |
||||
base |
X |
|||||
|
dict |
? |
||||
get |
X |
|||||
set__, __delete |
X |
|||||
X |
? |
|||||
init |
X |
X |
X |
|||
X |
? |
? |
||||
new |
X |
X |
? |
? |
||
X |
X |
? |
? |
|||
X |
X |
|||||
< |
|
bases |
~ |
|||
< |
|
mro |
~ |
|||
[ |
|
|||||
void * |
subclasses |
|||||
|
||||||
( |
||||||
unsigned int |
||||||
del |
X |
|||||
unsigned char |
||||||
подслоты¶sub-slots
Слот |
специальные методы |
|
|---|---|---|
await |
||
aiter |
||
anext |
||
add__ __radd |
||
iadd |
||
sub__ __rsub |
||
isub |
||
mul__ __rmul |
||
imul |
||
mod__ __rmod |
||
imod |
||
divmod__ __rdivmod |
||
pow__ __rpow |
||
ipow |
||
neg |
||
pos |
||
abs |
||
bool |
||
invert |
||
lshift__ __rlshift |
||
ilshift |
||
rshift__ __rrshift |
||
irshift |
||
and__ __rand |
||
iand |
||
xor__ __rxor |
||
ixor |
||
or__ __ror |
||
ior |
||
int |
||
void * |
||
float |
||
floordiv |
||
ifloordiv |
||
truediv |
||
itruediv |
||
index |
||
matmul__ __rmatmul |
||
imatmul |
||
len |
||
getitem |
||
setitem__, __delitem |
||
len |
||
add |
||
mul |
||
getitem |
||
setitem__ __delitem |
||
contains |
||
iadd |
||
imul |
||
Синонимы типов слотов¶slot typedefs
typedef |
Типы параметров |
Тип возвращаемого значения |
|---|---|---|
|
||
|
void |
|
void * |
void |
|
int |
||
|
||
int |
||
|
|
|
PyObject *const char *
|
|
|
int |
||
|
||
int |
||
|
||
int |
||
|
Py_hash_t |
|
|
||
|
|
|
|
|
|
|
||
int |
||
void |
||
|
int |
|
PyObject * |
|
|
|
||
|
||
|
||
int |
||
int |
||
int |
Подробнее см. определения типов слотов ниже.
Определение PyTypeObject¶PyTypeObject Definition
Определение структуры для PyTypeObject можно найти в
Include/cpython/object.h. Для удобства здесь повторяется
определение, приведённое там:
typedef struct _typeobject {
PyObject_VAR_HEAD
const char *tp_name; /* Для вывода в формате "<module>.<name>" */
Py_ssize_t tp_basicsize, tp_itemsize; /* Для выделения памяти */
/* Методы для реализации стандартных операций */
destructor tp_dealloc;
Py_ssize_t tp_vectorcall_offset;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
PyAsyncMethods *tp_as_async; /* ранее известный как tp_compare (Python 2)
или tp_reserved (Python 3) */
reprfunc tp_repr;
/* Наборы методов для стандартных классов */
PyNumberMethods *tp_as_number;
PySequenceMethods *tp_as_sequence;
PyMappingMethods *tp_as_mapping;
/* Дополнительные стандартные операции (здесь для двоичной совместимости) */
hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;
/* Функции для доступа к объекту как к буферу ввода/вывода */
PyBufferProcs *tp_as_buffer;
/* Флаги для определения наличия опциональных/расширенных возможностей */
unsigned long tp_flags;
const char *tp_doc; /* Строка документации */
/* Назначенное значение в версии 2.0 */
/* вызов функции для всех доступных объектов */
traverseproc tp_traverse;
/* удаление ссылок на содержащиеся объекты */
inquiry tp_clear;
/* Назначенное значение в версии 2.1 */
/* расширенные сравнения */
richcmpfunc tp_richcompare;
/* включение слабых ссылок */
Py_ssize_t tp_weaklistoffset;
/* Итераторы */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Дескриптор атрибутов и механизмы подклассов */
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
// Сильная ссылка на тип в куче, заимствованная ссылка на статический тип
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
Py_ssize_t tp_dictoffset;
initproc tp_init;
allocfunc tp_alloc;
newfunc tp_new;
freefunc tp_free; /* Низкоуровневая процедура освобождения памяти */
inquiry tp_is_gc; /* Для PyObject_IS_GC */
PyObject *tp_bases;
PyObject *tp_mro; /* порядок разрешения методов */
PyObject *tp_cache;
PyObject *tp_subclasses;
PyObject *tp_weaklist;
destructor tp_del;
/* Метка версии кэша атрибутов типа. Добавлено в версии 2.6. */
unsigned int tp_version_tag;
destructor tp_finalize;
vectorcallfunc tp_vectorcall;
/* битовый набор, указывающий, какие наблюдатели типов следят за этим типом */
unsigned char tp_watched;
} PyTypeObject;
Слоты PyObject¶PyObject Slots
Структура объекта типа расширяет структуру PyVarObject. Поле
ob_size используется для динамических типов (создаваемых с помощью type_new(),
обычно вызываемого из инструкции class). Обратите внимание, что PyType_Type (метатип)
инициализирует tp_itemsize, что означает, что его экземпляры (т.е.
объекты типов) должны иметь поле ob_size.
-
Py_ssize_t PyObject.ob_refcnt¶
- Часть Stable ABI.
Это счётчик ссылок объекта-типа, инициализируется значением
1макросомPyObject_HEAD_INIT. Обратите внимание: для статически выделенных объектов-типов экземпляры типа (объекты, у которыхob_typeуказывает обратно на тип) не считаются ссылками. Но для динамически выделенных объектов-типов экземпляры действительно считаются ссылками.Наследование:
Это поле не наследуется подтипами.
-
PyTypeObject *PyObject.ob_type¶
- Часть Stable ABI.
Это тип типа, иными словами, его метатип. Он инициализируется аргументом макроса
PyObject_HEAD_INIT, и его значением обычно должно быть&PyType_Type. Однако для динамически загружаемых модулей расширения, которые должны работать на Windows (по крайней мере), компилятор сообщает, что это недопустимый инициализатор. Поэтому принято передаватьNULLмакросуPyObject_HEAD_INITи явно инициализировать это поле в начале функции инициализации модуля, перед любыми другими действиями. Обычно это делается так:Foo_Type.ob_type = &PyType_Type;
Это должно быть сделано до создания любых экземпляров типа.
PyType_Ready()проверяет, равен лиob_typeзначениюNULL, и если да, инициализирует его значением поляob_typeбазового класса.PyType_Ready()не будет изменять это поле, если оно ненулевое.Наследование:
Это поле наследуется подтипами.
-
PyObject *PyObject._ob_next¶
-
PyObject *PyObject._ob_prev¶
Эти поля присутствуют только если определён макрос
Py_TRACE_REFS(см.configure --with-trace-refs option).Их инициализация значением
NULLвыполняется макросомPyObject_HEAD_INIT. Для статически размещённых объектов эти поля всегда остаютсяNULL. Для динамически размещённых объектов эти два поля используются для включения объекта в двусвязный список всех живых объектов в куче.Это можно использовать для различных целей отладки; в настоящее время используется только в функции
sys.getobjects()и для вывода объектов, которые остаются живыми в конце выполнения, когда установлена переменная окруженияPYTHONDUMPREFS.Наследование:
Эти поля не наследуются подтипами.
Слоты PyVarObject¶PyVarObject Slots
-
Py_ssize_t PyVarObject.ob_size¶
- Часть Stable ABI.
Для статически выделенных объектов типов это поле должно быть инициализировано нулём. Для динамически выделенных объектов типов это поле имеет особый внутренний смысл.
Доступ к этому полю должен осуществляться с помощью макросов
Py_SIZE()иPy_SET_SIZE().Наследование:
Это поле не наследуется подтипами.
Слоты PyTypeObject¶PyTypeObject Slots
Каждый слот имеет раздел, описывающий наследование. Если PyType_Ready()
может устанавливать значение, когда поле установлено в NULL, то также будет
раздел «Default» (значение по умолчанию). (Обратите внимание, что многие поля, заданные в PyBaseObject_Type
и PyType_Type, фактически действуют как значения по умолчанию.)
-
const char *PyTypeObject.tp_name¶
Указатель на строку, завершающуюся NUL, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов это должно быть просто имя типа. Если модуль является подмодулем пакета, полное имя пакета является частью полного имени модуля. Например, тип с именем
T, определённый в модулеMв подпакетеQпакетаP, должен иметь инициализаторtp_nameсо значением"P.Q.M.T".Для динамически выделенных объектов типов это должно быть просто имя типа, а имя модуля должно быть явно сохранено в словаре типа как значение для ключа
'__module__'.Для статически размещённых объектов типов, поле tp_name должно содержать точку. Всё до последней точки становится доступно как атрибут
__module__, а всё после последней точки – как атрибут__name__.Если точка отсутствует, всё поле
tp_nameстановится доступным как атрибут__name__, а атрибут__module__не определён (если только не задан явно в словаре, как описано выше). Это означает, что ваш тип невозможно будет сериализовать с помощью pickle. Кроме того, он не будет отображаться в документации модуля, создаваемой pydoc.Это поле не должно быть
NULL. Это единственное обязательное поле вPyTypeObject()(кроме потенциальноtp_itemsize).Наследование:
Это поле не наследуется подтипами.
-
Py_ssize_t PyTypeObject.tp_basicsize¶
-
Py_ssize_t PyTypeObject.tp_itemsize¶
Эти поля позволяют вычислить размер экземпляров типа в байтах.
Существует два вида типов: типы с экземплярами фиксированной длины имеют нулевое поле
tp_itemsize, типы с экземплярами переменной длины имеют ненулевое полеtp_itemsize. Для типа с экземплярами фиксированной длины все экземпляры имеют одинаковый размер, заданный вtp_basicsize. (Исключения из этого правила могут быть сделаны с помощьюPyUnstable_Object_GC_NewWithExtraData().)Для типа с экземплярами переменной длины экземпляры должны иметь поле
ob_size, а размер экземпляра равенtp_basicsizeплюс N разtp_itemsize, где N – это «длина» объекта.Функции, подобные
PyObject_NewVar(), принимают значение N в качестве аргумента и сохраняют его в полеob_sizeэкземпляра. Обратите внимание, что полеob_sizeвпоследствии может использоваться для других целей. Например, экземплярыintиспользуют битыob_sizeв определённом реализацией способе; доступ к нижележащему хранилищу и его размеру следует осуществлять с помощьюPyLong_Export().Примечание
К полю
ob_sizeследует обращаться с помощью макросовPy_SIZE()иPy_SET_SIZE().Кроме того, наличие поля
ob_sizeв структуре экземпляра не означает, что структура экземпляра имеет переменную длину. Например, типlistимеет экземпляры фиксированной длины, но эти экземпляры содержат полеob_size. (Как и в случае сint, избегайте прямого чтенияob_sizeсписков. Вместо этого вызывайтеPyList_Size().)Поле
tp_basicsizeвключает размер, необходимый для данныхtp_baseтипа, а также любые дополнительные данные, необходимые каждому экземпляру.Правильный способ установки
tp_basicsize– использовать операторsizeofдля структуры, используемой для объявления структуры экземпляра. Эта структура должна включать структуру, используемую для объявления базового типа. Другими словами,tp_basicsizeдолжно быть больше или равноtp_basicsizeбазового типа.Поскольку каждый тип является подтипом
object, эта структура должна включатьPyObjectилиPyVarObject(в зависимости от того, должен ли быть включёнob_size). Обычно они определяются макросомPyObject_HEADилиPyObject_VAR_HEADсоответственно.Базовый размер не включает размер заголовка GC, поскольку этот заголовок не является частью
PyObject_HEAD.Для случаев, когда структура, используемая для объявления базового типа, неизвестна, см.
PyType_Spec.basicsizeиPyType_FromMetaclass().Примечания о выравнивании:
tp_basicsizeдолжно быть кратно_Alignof(PyObject). При использованииsizeofвstruct, включающемPyObject_HEAD, как рекомендуется, компилятор обеспечивает это. При отказе от C-структурыstructили при использовании расширений компилятора, таких как__attribute__((packed)), ответственность ложится на вас.Если элементы переменной части требуют определённого выравнивания,
tp_basicsizeиtp_itemsizeдолжны быть кратны этому выравниванию. Например, если переменная часть типа хранитdouble, вы обязаны убедиться, что оба поля кратны_Alignof(double).
Наследование:
Эти поля наследуются подтипами по отдельности. (То есть, если поле установлено в ноль,
PyType_Ready()скопирует значение из базового типа, указывая, что экземпляры не нуждаются в дополнительном хранилище.)Если базовый тип имеет ненулевое
tp_itemsize, обычно небезопасно устанавливатьtp_itemsizeв другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).
-
destructor PyTypeObject.tp_dealloc¶
Указатель на функцию-деструктор экземпляра. Эта функция должна быть определена, если только тип не гарантирует, что его экземпляры никогда не будут освобождены (как в случае с синглетонами
NoneиEllipsis). Сигнатура функции:void tp_dealloc(PyObject *self);
Функция-деструктор вызывается макросами
Py_DECREF()иPy_XDECREF(), когда новое значение счётчика ссылок становится нулевым. В этот момент экземпляр всё ещё существует, но на него нет ссылок. Функция-деструктор должна освободить все ссылки, которыми владеет экземпляр, освободить все буферы памяти, принадлежащие экземпляру (с использованием функции освобождения, соответствующей функции выделения, использованной для выделения буфера), и вызвать функциюtp_freeтипа. Если тип не является субтипируемым (не имеет установленного флагаPy_TPFLAGS_BASETYPE), допускается вызывать деаллокатор объекта напрямую, а не черезtp_free. Деаллокатор объекта должен быть тем же, что использовался для выделения экземпляра; обычно этоPyObject_Del(), если экземпляр был выделен с помощьюPyObject_NewилиPyObject_NewVar, илиPyObject_GC_Del(), если экземпляр был выделен с помощьюPyObject_GC_NewилиPyObject_GC_NewVar.Если тип поддерживает сборку мусора (имеет установленный флаг
Py_TPFLAGS_HAVE_GC), деструктор должен вызватьPyObject_GC_UnTrack()перед очисткой любых полей-членов.static void foo_dealloc(foo_object *self) { PyObject_GC_UnTrack(self); Py_CLEAR(self->ref); Py_TYPE(self)->tp_free((PyObject *)self); }
Наконец, если тип выделен в куче (
Py_TPFLAGS_HEAPTYPE), деаллокатор должен освободить принадлежащую ему ссылку на объект-тип (черезPy_DECREF()) после вызова деаллокатора типа. Чтобы избежать висячих указателей, рекомендуемый способ сделать это:static void foo_dealloc(foo_object *self) { PyTypeObject *tp = Py_TYPE(self); // Освободить ссылки и буферы здесь. tp->tp_free(self); Py_DECREF(tp); }
Предупреждение
В Python со сборкой мусора
tp_deallocможет вызываться из любого потока Python, а не только из потока, создавшего объект (если объект становится частью цикла ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Это не проблема для вызовов API Python, поскольку поток, в котором вызываетсяtp_dealloc, будет владеть Глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект в свою очередь уничтожает объекты из какой-либо другой библиотеки C или C++, следует проявить осторожность, чтобы уничтожение этих объектов в потоке, вызвавшемtp_dealloc, не нарушило никаких предположений библиотеки.Наследование:
Это поле наследуется подтипами.
-
Py_ssize_t PyTypeObject.tp_vectorcall_offset¶
Необязательное смещение к поинстансной функции, реализующей вызов объекта с помощью протокола vectorcall, более эффективная альтернатива более простому
tp_call.Это поле используется только в том случае, если установлен флаг
Py_TPFLAGS_HAVE_VECTORCALL. В этом случае оно должно быть положительным целым числом, содержащим смещение в экземпляре указателяvectorcallfunc.Указатель vectorcallfunc может быть
NULL, и в этом случае экземпляр ведёт себя так, как если быPy_TPFLAGS_HAVE_VECTORCALLне был установлен: вызов экземпляра сводится кtp_call.Любой класс, устанавливающий
Py_TPFLAGS_HAVE_VECTORCALL, должен также установитьtp_callи убедиться, что его поведение согласуется с функцией vectorcallfunc. Это можно сделать, установив tp_call вPyVectorcall_Call().Изменено в версии 3.8: До версии 3.8 этот слот назывался
tp_print. В Python 2.x он использовался для вывода в файл. В Python 3.0–3.7 он не использовался.Изменено в версии 3.12: До версии 3.12 не рекомендовалось для изменяемых типов, размещаемых в куче реализовывать протокол vectorcall. Когда пользователь устанавливает
__call__в коде Python, обновляется только tp_call, что, вероятно, делает его несовместимым с функцией vectorcall. Начиная с версии 3.12, установка__call__отключает оптимизацию vectorcall путём сброса флагаPy_TPFLAGS_HAVE_VECTORCALL.Наследование:
Это поле всегда наследуется. Однако флаг
Py_TPFLAGS_HAVE_VECTORCALLнаследуется не всегда. Если он не установлен, то подкласс не будет использовать vectorcall, за исключением случаев, когдаPyVectorcall_Call()вызывается явно.
-
getattrfunc PyTypeObject.tp_getattr¶
Необязательный указатель на функцию получения строки атрибута.
Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция
tp_getattro, но принимает C-строку вместо строкового объекта Python для указания имени атрибута.Наследование:
Группа:
tp_getattr,tp_getattroЭто поле наследуется подтипами вместе с
tp_getattro: подтип наследует иtp_getattr, иtp_getattroот своего базового типа, когдаtp_getattrиtp_getattroподтипа оба равныNULL.
-
setattrfunc PyTypeObject.tp_setattr¶
Необязательный указатель на функцию для установки и удаления атрибутов.
Это поле устарело. Если оно определено, оно должно указывать на функцию, которая действует так же, как функция
tp_setattro, но принимает C-строку вместо строкового объекта Python для указания имени атрибута.Наследование:
Группа:
tp_setattr,tp_setattroЭто поле наследуется подтипами вместе с
tp_setattro: подтип наследует иtp_setattr, иtp_setattroот своего базового типа, когдаtp_setattrиtp_setattroподтипа оба равныNULL.
-
PyAsyncMethods *PyTypeObject.tp_as_async¶
Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протоколы ожидаемого объекта и асинхронного итератора на уровне C. Подробнее см. в Структуры асинхронных объектов.
Добавлено в версии 3.5: Ранее было известно как
tp_compareиtp_reserved.Наследование:
Поле
tp_as_asyncне наследуется, но содержащиеся в нем поля наследуются по отдельности.
-
reprfunc PyTypeObject.tp_repr¶
Необязательный указатель на функцию, реализующую встроенную функцию
repr().Сигнатура такая же, как для
PyObject_Repr():PyObject *tp_repr(PyObject *self);
Функция должна возвращать строку или объект Unicode. В идеале она должна возвращать строку, которая при передаче в
eval()в подходящем окружении возвращает объект с тем же значением. Если это невозможно, она должна возвращать строку, начинающуюся с'<'и заканчивающуюся'>', из которой можно вывести как тип, так и значение объекта.Наследование:
Это поле наследуется подтипами.
По умолчанию:
Если это поле не задано, возвращается строка вида
<%s object at %p>, где%sзаменяется именем типа, а%p– адресом памяти объекта.
-
PyNumberMethods *PyTypeObject.tp_as_number¶
Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих числовой протокол. Эти поля описаны в Структуры числовых объектов.
Наследование:
Поле
tp_as_numberне наследуется, но содержащиеся в нём поля наследуются по отдельности.
-
PySequenceMethods *PyTypeObject.tp_as_sequence¶
Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол последовательности. Эти поля описаны в Структуры объектов-последовательностей.
Наследование:
Поле
tp_as_sequenceне наследуется, но содержащиеся в нём поля наследуются по отдельности.
-
PyMappingMethods *PyTypeObject.tp_as_mapping¶
Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих протокол отображения. Эти поля описаны в Структуры объектов-отображений.
Наследование:
Поле
tp_as_mappingне наследуется, но содержащиеся в нём поля наследуются по отдельности.
-
hashfunc PyTypeObject.tp_hash¶
Необязательный указатель на функцию, реализующую встроенную функцию
hash().Сигнатура такая же, как для
PyObject_Hash():Py_hash_t tp_hash(PyObject *);
Значение
-1не должно возвращаться как обычное возвращаемое значение; при возникновении ошибки во время вычисления хеш-значения функция должна установить исключение и вернуть-1.Если это поле не задано (и
tp_richcompareне задано), то попытка получить хеш объекта вызываетTypeError. Это то же самое, что установить его вPyObject_HashNotImplemented().Это поле можно явно установить в
PyObject_HashNotImplemented(), чтобы заблокировать наследование хеш-метода от родительского типа. Это интерпретируется как эквивалент__hash__ = Noneна уровне Python, в результате чегоisinstance(o, collections.Hashable)корректно возвращаетFalse. Обратите внимание, что верно и обратное: установка__hash__ = Noneв классе на уровне Python приведет к тому, что слотtp_hashбудет установлен вPyObject_HashNotImplemented().Наследование:
Группа:
tp_hash,tp_richcompareЭто поле наследуется подтипами вместе с
tp_richcompare: подтип наследует какtp_richcompare, так иtp_hash, еслиtp_richcompareиtp_hashподтипа равныNULL.
-
ternaryfunc PyTypeObject.tp_call¶
Необязательный указатель на функцию, реализующую вызов объекта. Это значение должно быть
NULL, если объект не является вызываемым. Сигнатура такая же, как уPyObject_Call():PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwargs);
Наследование:
Это поле наследуется подтипами.
-
reprfunc PyTypeObject.tp_str¶
Необязательный указатель на функцию, реализующую встроенную операцию
str(). (Обратите внимание, чтоstrтеперь является типом, аstr()вызывает конструктор этого типа. Этот конструктор вызываетPyObject_Str()для выполнения фактической работы, иPyObject_Str()будет вызывать этот обработчик.)Сигнатура такая же, как для
PyObject_Str():PyObject *tp_str(PyObject *self);
Функция должна возвращать строку или объект Unicode. Это должно быть «дружественное» строковое представление объекта, так как это представление будет использоваться, в частности, функцией
print().Наследование:
Это поле наследуется подтипами.
По умолчанию:
Если это поле не задано, вызывается
PyObject_Repr()для возврата строкового представления.
-
getattrofunc PyTypeObject.tp_getattro¶
Необязательный указатель на функцию получения атрибута.
Сигнатура такая же, как для
PyObject_GetAttr():PyObject *tp_getattro(PyObject *self, PyObject *attr);
Обычно удобно установить это поле в
PyObject_GenericGetAttr(), которое реализует обычный способ поиска атрибутов объекта.Наследование:
Группа:
tp_getattr,tp_getattroЭто поле наследуется подтипами вместе с
tp_getattr: подтип наследует иtp_getattr, иtp_getattroот своего базового типа, когдаtp_getattrиtp_getattroподтипа оба равныNULL.По умолчанию:
PyBaseObject_TypeиспользуетPyObject_GenericGetAttr().
-
setattrofunc PyTypeObject.tp_setattro¶
Необязательный указатель на функцию для установки и удаления атрибутов.
Сигнатура такая же, как для
PyObject_SetAttr():int tp_setattro(PyObject *self, PyObject *attr, PyObject *value);
Кроме того, установка value в
NULLдля удаления атрибута должна поддерживаться. Обычно удобно устанавливать это поле вPyObject_GenericSetAttr(), которое реализует обычный способ установки атрибутов объекта.Наследование:
Группа:
tp_setattr,tp_setattroЭто поле наследуется подтипами вместе с
tp_setattr: подтип наследует иtp_setattr, иtp_setattroот своего базового типа, когдаtp_setattrиtp_setattroподтипа оба равныNULL.По умолчанию:
PyBaseObject_TypeиспользуетPyObject_GenericSetAttr().
-
PyBufferProcs *PyTypeObject.tp_as_buffer¶
Указатель на дополнительную структуру, содержащую поля, значимые только для объектов, реализующих буферный интерфейс. Эти поля описаны в Buffer Object Structures.
Наследование:
Поле
tp_as_bufferне наследуется, но содержащиеся в нем поля наследуются по отдельности.
-
unsigned long PyTypeObject.tp_flags¶
Это поле представляет собой битовую маску различных флагов. Некоторые флаги указывают на изменённую семантику для определённых ситуаций; другие используются для указания того, что определённые поля в объекте типа (или в расширяющих структурах, на которые ссылаются через
tp_as_number,tp_as_sequence,tp_as_mappingиtp_as_buffer), которые исторически не всегда присутствовали, теперь действительны; если такой бит флага сброшен, то поля типа, которые он защищает, не должны использоваться и должны считаться имеющими значение ноль илиNULL.Наследование:
Наследование этого поля устроено сложно. Большинство битов флагов наследуются индивидуально: если у базового типа установлен бит флага, подтип наследует этот бит. Биты флагов, относящиеся к структурам расширения, наследуются строго вместе с самой структурой расширения – значение бита флага базового типа копируется в подтип вместе с указателем на структуру расширения. Бит флага
Py_TPFLAGS_HAVE_GCнаследуется вместе с полямиtp_traverseиtp_clear: если в подтипе битPy_TPFLAGS_HAVE_GCсброшен, а поляtp_traverseиtp_clearв подтипе существуют и имеют значенияNULL. .. XXX действительно ли большинство битов флагов наследуются индивидуально?По умолчанию:
PyBaseObject_TypeиспользуетPy_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE.Битовые маски:
В настоящее время определены следующие битовые маски; их можно объединять с помощью оператора
|для получения значения поляtp_flags. МакросPyType_HasFeature()принимает тип и значение флагов, tp и f, и проверяет, является лиtp->tp_flags & fненулевым.-
Py_TPFLAGS_HEAPTYPE¶
Этот бит устанавливается, когда сам объект типа выделяется в куче, например, типы, созданные динамически с помощью
PyType_FromSpec(). В этом случае полеob_typeего экземпляров считается ссылкой на тип, и объект типа инкрементируется (INCREF) при создании нового экземпляра, и декрементируется (DECREF) при уничтожении экземпляра (это не относится к экземплярам подтипов; только тип, на который ссылается ob_type экземпляра, инкрементируется или декрементируется). Типы в куче также должны поддерживать сборку мусора так как они могут образовывать циклические ссылки с собственным объектом модуля.Наследование:
???
-
Py_TPFLAGS_BASETYPE¶
Этот бит устанавливается, когда тип может использоваться как базовый тип другого типа. Если этот бит сброшен, тип не может быть унаследован (аналогично «финальному» классу в Java).
Наследование:
???
-
Py_TPFLAGS_READY¶
Этот бит устанавливается, когда объект типа был полностью инициализирован функцией
PyType_Ready().Наследование:
???
-
Py_TPFLAGS_READYING¶
Этот бит устанавливается, пока
PyType_Ready()находится в процессе инициализации объекта типа.Наследование:
???
-
Py_TPFLAGS_HAVE_GC¶
Этот бит устанавливается, когда объект поддерживает сборку мусора. Если бит установлен, экземпляры должны создаваться с помощью
PyObject_GC_Newи уничтожаться с помощьюPyObject_GC_Del(). Дополнительная информация – в разделе Поддержка циклической сборки мусора. Этот бит также означает, что связанные со сборкой мусора поляtp_traverseиtp_clearприсутствуют в объекте типа.Наследование:
Группа:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearБит флага
Py_TPFLAGS_HAVE_GCнаследуется вместе с полямиtp_traverseиtp_clear, то есть если бит флагаPy_TPFLAGS_HAVE_GCсброшен в подтипе, а поляtp_traverseиtp_clearв подтипе существуют и имеют значенияNULL.
-
Py_TPFLAGS_DEFAULT¶
Это битовая маска всех битов, относящихся к наличию определённых полей в объекте типа и его структурах расширения. В настоящее время она включает следующие биты:
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION.Наследование:
???
-
Py_TPFLAGS_METHOD_DESCRIPTOR¶
Этот бит указывает, что объекты ведут себя как несвязанные методы.
Если этот флаг установлен для
type(meth), то:meth.__get__(obj, cls)(*args, **kwds)(приobjне None) должен быть эквивалентенmeth(obj, *args, **kwds).meth.__get__(None, cls)(*args, **kwds)должен быть эквивалентенmeth(*args, **kwds).
Этот флаг включает оптимизацию для типичных вызовов методов, таких как
obj.meth(): он позволяет избежать создания временного объекта «связанный метод» дляobj.meth.Добавлено в версии 3.8.
Наследование:
Этот флаг никогда не наследуется типами, у которых не установлен флаг
Py_TPFLAGS_IMMUTABLETYPE. Для типов расширения он наследуется всякий раз, когда наследуетсяtp_descr_get.
-
Py_TPFLAGS_MANAGED_DICT¶
This bit indicates that instances of the class have a ~object.__dict__ attribute, and that the space for the dictionary is managed by the VM.
Если этот флаг установлен,
Py_TPFLAGS_HAVE_GCтакже должен быть установлен.Добавлено в версии 3.12.
Наследование:
Этот флаг наследуется, если только поле
tp_dictoffsetне установлено в суперклассе.
-
Py_TPFLAGS_MANAGED_WEAKREF¶
Этот бит указывает, что экземпляры класса должны поддерживать слабые ссылки.
Добавлено в версии 3.12.
Наследование:
Этот флаг наследуется, если только поле
tp_weaklistoffsetне установлено в суперклассе.
-
Py_TPFLAGS_ITEMS_AT_END¶
Применим только к типам переменного размера, то есть с ненулевым
tp_itemsize.Указывает, что часть переменного размера экземпляра этого типа находится в конце области памяти экземпляра, со смещением
Py_TYPE(obj)->tp_basicsize(которое может отличаться в каждом подклассе).При установке этого флага убедитесь, что все суперклассы либо используют такое же расположение в памяти, либо не являются типами переменного размера. Python не проверяет это условие.
Добавлено в версии 3.12.
Наследование:
Этот флаг наследуется.
-
Py_TPFLAGS_LONG_SUBCLASS¶
-
Py_TPFLAGS_LIST_SUBCLASS¶
-
Py_TPFLAGS_TUPLE_SUBCLASS¶
-
Py_TPFLAGS_BYTES_SUBCLASS¶
-
Py_TPFLAGS_UNICODE_SUBCLASS¶
-
Py_TPFLAGS_DICT_SUBCLASS¶
-
Py_TPFLAGS_BASE_EXC_SUBCLASS¶
-
Py_TPFLAGS_TYPE_SUBCLASS¶
These flags are used by functions such as
PyLong_Check()to quickly determine if a type is a subclass of a built-in type; such specific checks are faster than a generic check, likePyObject_IsInstance(). Custom types that inherit from built-ins should have theirtp_flagsset appropriately, or the code that interacts with such types will behave differently depending on what kind of check is used.
-
Py_TPFLAGS_HAVE_FINALIZE¶
Этот бит устанавливается, когда слот
tp_finalizeприсутствует в структуре типа.Добавлено в версии 3.4.
Устарело с версии 3.8: Этот флаг больше не нужен, так как интерпретатор предполагает, что слот
tp_finalizeвсегда присутствует в структуре типа.
-
Py_TPFLAGS_HAVE_VECTORCALL¶
Этот бит устанавливается, когда класс реализует протокол vectorcall. Подробнее см.
tp_vectorcall_offset.Наследование:
Этот бит наследуется, если
tp_callтакже наследуется.Добавлено в версии 3.9.
Изменено в версии 3.12: Теперь этот флаг удаляется из класса, когда
__call__()методу класса присваивается новое значение.Теперь этот флаг может наследоваться изменяемыми классами.
-
Py_TPFLAGS_IMMUTABLETYPE¶
Этот бит устанавливается для объектов типа, которые являются неизменяемыми: атрибуты типа нельзя ни установить, ни удалить.
PyType_Ready()автоматически применяет этот флаг к статическим типам.Наследование:
Этот флаг не наследуется.
Добавлено в версии 3.10.
-
Py_TPFLAGS_DISALLOW_INSTANTIATION¶
Запретить создание экземпляров типа: установить
tp_newв NULL и не создавать ключ__new__в словаре типа.Флаг должен быть установлен до создания типа, а не после. Например, его нужно установить до вызова
PyType_Ready()для этого типа.Флаг устанавливается автоматически для статических типов, если
tp_baseравен NULL или&PyBaseObject_Type, иtp_newравен NULL.Наследование:
Этот флаг не наследуется. Однако подклассы нельзя будет инстанцировать, если они не предоставят ненулевой
tp_new(что возможно только через C API).Примечание
Чтобы запретить прямое создание экземпляров класса, но разрешить создание его подклассов (например, для абстрактного базового класса), не используйте этот флаг. Вместо этого добейтесь, чтобы
tp_newзавершался успешно только для подклассов.Добавлено в версии 3.10.
-
Py_TPFLAGS_MAPPING¶
Этот бит указывает, что экземпляры класса могут сопоставляться с шаблонами отображений при использовании в качестве объекта оператора
match. Он автоматически устанавливается при регистрации или наследованииcollections.abc.Mappingи сбрасывается при регистрацииcollections.abc.Sequence.Примечание
Py_TPFLAGS_MAPPINGиPy_TPFLAGS_SEQUENCEвзаимоисключающие; одновременная активация обоих флагов является ошибкой.Наследование:
Этот флаг наследуется типами, которые ещё не установили
Py_TPFLAGS_SEQUENCE.См. также
PEP 634 – Структурное сопоставление с образцом: спецификация
Добавлено в версии 3.10.
-
Py_TPFLAGS_SEQUENCE¶
Этот бит указывает, что экземпляры класса могут сопоставляться с шаблонами последовательностей при использовании в качестве объекта оператора
match. Он автоматически устанавливается при регистрации или наследованииcollections.abc.Sequenceи сбрасывается при регистрацииcollections.abc.Mapping.Примечание
Py_TPFLAGS_MAPPINGиPy_TPFLAGS_SEQUENCEвзаимоисключающие; одновременная активация обоих флагов является ошибкой.Наследование:
Этот флаг наследуется типами, которые ещё не установили
Py_TPFLAGS_MAPPING.См. также
PEP 634 – Структурное сопоставление с образцом: спецификация
Добавлено в версии 3.10.
-
Py_TPFLAGS_VALID_VERSION_TAG¶
Внутренний флаг. Не устанавливайте и не сбрасывайте этот флаг. Чтобы указать, что класс изменился, вызовите
PyType_Modified()Предупреждение
This flag is present in header files, but is an internal feature and should not be used. It will be removed in a future version of CPython
-
Py_TPFLAGS_HEAPTYPE¶
-
const char *PyTypeObject.tp_doc¶
Необязательный указатель на C-строку, завершающуюся символом NUL, содержащую строку документации для данного объекта типа. Он доступен как атрибут
__doc__у типа и его экземпляров.Наследование:
Это поле не наследуется подтипами.
-
traverseproc PyTypeObject.tp_traverse¶
Необязательный указатель на функцию обхода для сборщика мусора. Используется только если установлен бит флага
Py_TPFLAGS_HAVE_GC. Сигнатура:int tp_traverse(PyObject *self, visitproc visit, void *arg);
Дополнительная информация о схеме сборки мусора в Python доступна в разделе Поддержка циклической сборки мусора.
Указатель
tp_traverseиспользуется сборщиком мусора для обнаружения циклических ссылок. Типичная реализация функцииtp_traverseпросто вызываетPy_VISIT()для каждого элемента экземпляра, являющегося объектом Python, которым владеет экземпляр. Например, это функцияlocal_traverse()из модуля расширения_thread:static int local_traverse(localobject *self, visitproc visit, void *arg) { Py_VISIT(self->args); Py_VISIT(self->kw); Py_VISIT(self->dict); return 0; }
Обратите внимание, что
Py_VISIT()вызывается только для тех членов, которые могут участвовать в циклических ссылках. Хотя есть также членself->key, он может быть толькоNULLили строкой Python и поэтому не может быть частью циклической ссылки.С другой стороны, даже если известно, что член никогда не может быть частью цикла, в качестве средства отладки его всё равно можно обойти, чтобы функция
get_referents()модуляgcвключила его.Предупреждение
При реализации
tp_traverseдолжны обходиться только те члены, которыми экземпляр владеет (имея на них сильные ссылки). Например, если объект поддерживает слабые ссылки через слотtp_weaklist, указатель, поддерживающий связанный список (то, на что указывает tp_weaklist), не должен обходиться, поскольку экземпляр не владеет напрямую слабыми ссылками на себя (список слабых ссылок существует для поддержки механизма слабых ссылок, но у экземпляра нет сильной ссылки на элементы внутри него, так как они могут быть удалены, даже если экземпляр всё ещё жив).Обратите внимание, что
Py_VISIT()требует, чтобы параметры visit и arg дляlocal_traverse()имели именно такие имена; не следует называть их как попало.Экземпляры кучевых типов содержат ссылку на свой тип. Поэтому их функция обхода должна либо обходить
Py_TYPE(self), либо делегировать эту ответственность путём вызоваtp_traverseдругого кучевого типа (например, кучевого суперкласса). Если этого не сделать, объект типа может не быть собран сборщиком мусора.Изменено в версии 3.9: Ожидается, что типы, выделяемые в куче, будут посещать
Py_TYPE(self)вtp_traverse. В более ранних версиях Python из-за ошибки 40217 это могло приводить к сбоям в подклассах.Наследование:
Группа:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearЭто поле наследуется подтипами вместе с
tp_clearи флагомPy_TPFLAGS_HAVE_GC: флаг,tp_traverseиtp_clearнаследуются от базового типа, если они равны нулю в подтипе.
-
inquiry PyTypeObject.tp_clear¶
Необязательный указатель на функцию очистки для сборщика мусора. Используется только если установлен флаг
Py_TPFLAGS_HAVE_GC. Сигнатура:int tp_clear(PyObject *);
Функция-член
tp_clearиспользуется для разрыва циклических ссылок в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности все функцииtp_clearв системе должны совместно разрывать все циклические ссылки. Это тонкий момент, и при любых сомнениях следует предоставить функциюtp_clear. Например, тип tuple не реализует функциюtp_clear, поскольку можно доказать, что ни одна циклическая ссылка не может состоять исключительно из кортежей. Поэтому функцииtp_clearдругих типов должны быть достаточны для разрыва любой циклической ссылки, содержащей кортеж. Это не очевидно, и редко есть веская причина избегать реализацииtp_clear.Реализации
tp_clearдолжны удалять ссылки экземпляра на те его члены, которые могут являться объектами Python, и устанавливать указатели на эти члены вNULL, как показано в следующем примере:static int local_clear(localobject *self) { Py_CLEAR(self->key); Py_CLEAR(self->args); Py_CLEAR(self->kw); Py_CLEAR(self->dict); return 0; }
Следует использовать макрос
Py_CLEAR(), потому что очистка ссылок – это деликатная операция: ссылка на содержащийся объект не должна освобождаться (черезPy_DECREF()) до тех пор, пока указатель на содержащийся объект не будет установлен вNULL. Это связано с тем, что освобождение ссылки может привести к тому, что содержащийся объект станет мусором, что вызовет цепочку действий по его утилизации, которая может включать выполнение произвольного кода Python (из-за финализаторов или колбэков слабых ссылок, связанных с содержащимся объектом). Если такой код может снова сослаться на self, важно, чтобы указатель на содержащийся объект в этот момент былNULL, чтобы self знал, что содержащийся объект больше нельзя использовать. МакросPy_CLEAR()выполняет операции в безопасном порядке.Обратите внимание, что
tp_clearвызывается не всегда перед освобождением экземпляра. Например, когда подсчёта ссылок достаточно, чтобы определить, что объект больше не используется, циклический сборщик мусора не задействуется, иtp_deallocвызывается напрямую.Поскольку цель функций
tp_clear– разрывать циклические ссылки, нет необходимости очищать содержащиеся объекты, такие как строки Python или целые числа Python, которые не могут участвовать в циклических ссылках. С другой стороны, может быть удобно очистить все содержащиеся объекты Python и написать функциюtp_deallocтипа так, чтобы она вызывалаtp_clear.Дополнительную информацию о схеме сборки мусора Python можно найти в разделе Поддержка циклической сборки мусора.
Наследование:
Группа:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearЭто поле наследуется подтипами вместе с
tp_traverseи флагомPy_TPFLAGS_HAVE_GC: флаг,tp_traverseиtp_clearнаследуются от базового типа, если они равны нулю в подтипе.
-
richcmpfunc PyTypeObject.tp_richcompare¶
Необязательный указатель на функцию расширенного сравнения, сигнатура которой:
PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);
Первый параметр гарантированно является экземпляром типа, определяемого через
PyTypeObject.Функция должна возвращать результат сравнения (обычно
Py_TrueилиPy_False). Если сравнение не определено, она должна вернутьPy_NotImplemented; если произошла другая ошибка, она должна вернутьNULLи установить условие исключения.Следующие константы определены для использования в качестве третьего аргумента для
tp_richcompareи дляPyObject_RichCompare():Константа
Сравнение
-
Py_LT¶
<-
Py_LE¶
<=-
Py_EQ¶
==-
Py_NE¶
!=-
Py_GT¶
>-
Py_GE¶
>=Для упрощения написания функций расширенного сравнения определён следующий макрос:
-
Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)¶
Возвращает
Py_TrueилиPy_Falseиз функции в зависимости от результата сравнения. VAL_A и VAL_B должны быть упорядочиваемыми с помощью операторов сравнения языка C (например, это могут быть значения типа int или float). Третий аргумент задаёт требуемую операцию, как и дляPyObject_RichCompare().Возвращаемое значение – это новая сильная ссылка.
В случае ошибки устанавливает исключение и возвращает
NULLиз функции.Добавлено в версии 3.7.
Наследование:
Группа:
tp_hash,tp_richcompareЭто поле наследуется подтипами вместе с
tp_hash: подтип наследуетtp_richcompareиtp_hash, когдаtp_richcompareиtp_hashподтипа обаNULL.По умолчанию:
PyBaseObject_Typeпредоставляет реализациюtp_richcompare, которая может быть унаследована. Однако, если определено толькоtp_hash, унаследованная функция не используется, и экземпляры типа не смогут участвовать в сравнениях.-
Py_LT¶
-
Py_ssize_t PyTypeObject.tp_weaklistoffset¶
Хотя это поле всё ещё поддерживается,
Py_TPFLAGS_MANAGED_WEAKREFследует использовать вместо него, если это возможно.Если экземпляры этого типа поддерживают слабые ссылки, это поле больше нуля и содержит смещение в структуре экземпляра до головы списка слабых ссылок (игнорируя заголовок GC, если он присутствует); это смещение используется функциями
PyObject_ClearWeakRefs()иPyWeakref_*. Структура экземпляра должна содержать поле типа PyObject*, которое инициализируетсяNULL.Не путайте это поле с
tp_weaklist; это голова списка для слабых ссылок на сам объект типа.Установка обоих битов
Py_TPFLAGS_MANAGED_WEAKREFиtp_weaklistoffsetявляется ошибкой.Наследование:
Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что подтип использует другую голову списка слабых ссылок, нежели базовый тип. Поскольку голова списка всегда находится через
tp_weaklistoffset, это не должно быть проблемой.По умолчанию:
Если бит
Py_TPFLAGS_MANAGED_WEAKREFустановлен в полеtp_flags, тоtp_weaklistoffsetбудет установлено в отрицательное значение, чтобы указать, что использовать это поле небезопасно.
-
getiterfunc PyTypeObject.tp_iter¶
Необязательный указатель на функцию, возвращающую итератор для объекта. Его наличие обычно означает, что экземпляры этого типа являются итерируемыми (хотя последовательности могут быть итерируемыми и без этой функции).
Эта функция имеет ту же сигнатуру, что и
PyObject_GetIter():PyObject *tp_iter(PyObject *self);
Наследование:
Это поле наследуется подтипами.
-
iternextfunc PyTypeObject.tp_iternext¶
Необязательный указатель на функцию, возвращающую следующий элемент итератора. Сигнатура:
PyObject *tp_iternext(PyObject *self);
Когда итератор исчерпан, он должен возвращать
NULL; исключениеStopIterationможет быть установлено или нет. При другой ошибке он также должен возвращатьNULL. Его наличие означает, что экземпляры этого типа являются итераторами.Типы-итераторы также должны определять функцию
tp_iter, и эта функция должна возвращать сам экземпляр итератора (не новый экземпляр итератора).Эта функция имеет ту же сигнатуру, что и
PyIter_Next().Наследование:
Это поле наследуется подтипами.
-
struct PyMethodDef *PyTypeObject.tp_methods¶
Необязательный указатель на статический массив структур
PyMethodDef, завершающийсяNULL, объявляющий обычные методы этого типа.Для каждой записи в массиве в словарь типа добавляется запись (см.
tp_dictниже), содержащая дескриптор метода.Наследование:
Это поле не наследуется подтипами (методы наследуются через другой механизм).
-
struct PyMemberDef *PyTypeObject.tp_members¶
Необязательный указатель на статический массив
PyMemberDefструктур, завершающийсяNULL, объявляющий обычные элементы данных (поля или слоты) экземпляров этого типа.Для каждой записи в массиве в словарь типа добавляется запись, содержащая дескриптор члена (см.
tp_dictниже).Наследование:
Это поле не наследуется подтипами (члены наследуются через другой механизм).
-
struct PyGetSetDef *PyTypeObject.tp_getset¶
Необязательный указатель на статический массив
PyGetSetDefструктур, завершающийсяNULL, объявляющий вычисляемые атрибуты экземпляров этого типа.Для каждой записи в массиве в словарь типа добавляется запись, содержащая дескриптор getset (см.
tp_dictниже).Наследование:
Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).
-
PyTypeObject *PyTypeObject.tp_base¶
Необязательный указатель на базовый тип, от которого наследуются свойства типа. На этом уровне поддерживается только одиночное наследование; множественное наследование требует динамического создания объекта типа вызовом метатипа.
Примечание
Инициализация слотов подчиняется правилам инициализации глобальных переменных. C99 требует, чтобы инициализаторы были «адресными константами». Обозначения функций, такие как
PyType_GenericNew(), с неявным преобразованием в указатель, являются допустимыми адресными константами C99.Однако унарный оператор '&', применённый к нестатической переменной, такой как
PyBaseObject_Type, не обязан давать адресную константу. Компиляторы могут это поддерживать (gcc поддерживает), MSVC – нет. Оба компилятора в этом конкретном поведении строго соответствуют стандарту.Следовательно,
tp_baseдолжно устанавливаться в функции инициализации модуля расширения.Наследование:
Это поле не наследуется подтипами (очевидно).
По умолчанию:
По умолчанию это поле равно
&PyBaseObject_Type(которое программистам Python известно как типobject).
-
PyObject *PyTypeObject.tp_dict¶
Словарь типа сохраняется здесь с помощью
PyType_Ready().Обычно это поле должно быть инициализировано значением
NULLперед вызовом PyType_Ready; оно также может быть инициализировано словарём, содержащим начальные атрибуты типа. После того какPyType_Ready()инициализировал тип, в этот словарь можно добавлять дополнительные атрибуты только в том случае, если они не соответствуют перегруженным операциям (например,__add__()). После завершения инициализации типа это поле должно считаться доступным только для чтения.Некоторые типы могут не хранить свой словарь в этом слоте. Используйте
PyType_GetDict()для получения словаря для произвольного типа.Изменено в версии 3.12: Детали реализации: для статических встроенных типов это всегда
NULL. Вместо этого словарь для таких типов хранится вPyInterpreterState. ИспользуйтеPyType_GetDict()для получения словаря для произвольного типа.Наследование:
Это поле не наследуется подтипами (хотя определённые здесь атрибуты наследуются через другой механизм).
По умолчанию:
Если это поле равно
NULL,PyType_Ready()назначит ему новый словарь.Предупреждение
Небезопасно использовать
PyDict_SetItem()на или иным образом изменятьtp_dictс помощью C-API словаря.
-
descrgetfunc PyTypeObject.tp_descr_get¶
Необязательный указатель на функцию «descriptor get».
Сигнатура функции:
PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);
Наследование:
Это поле наследуется подтипами.
-
descrsetfunc PyTypeObject.tp_descr_set¶
Необязательный указатель на функцию для установки и удаления значения дескриптора.
Сигнатура функции:
int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
Аргумент value устанавливается в
NULLдля удаления значения.Наследование:
Это поле наследуется подтипами.
-
Py_ssize_t PyTypeObject.tp_dictoffset¶
Хотя это поле всё ещё поддерживается, следует использовать
Py_TPFLAGS_MANAGED_DICTвместо него, если это возможно.Если экземпляры этого типа имеют словарь, содержащий переменные экземпляра, это поле не равно нулю и содержит смещение в структуре экземпляра для словаря переменных экземпляра; это смещение используется
PyObject_GenericGetAttr().Не путайте это поле с
tp_dict; это словарь для атрибутов самого объекта типа.Значение задаёт смещение словаря относительно начала структуры экземпляра.
tp_dictoffsetследует рассматривать как доступный только для записи. Чтобы получить указатель на словарь, вызовитеPyObject_GenericGetDict(). ВызовPyObject_GenericGetDict()может потребовать выделения памяти для словаря, поэтому может быть эффективнее вызватьPyObject_GetAttr()при доступе к атрибуту объекта.Установка обоих битов
Py_TPFLAGS_MANAGED_DICTиtp_dictoffsetявляется ошибкой.Наследование:
Это поле наследуется подтипами. Подтип не должен переопределять это смещение; это может быть небезопасно, если код C попытается получить доступ к словарю по предыдущему смещению. Для корректной поддержки наследования используйте
Py_TPFLAGS_MANAGED_DICT.По умолчанию:
Этот слот не имеет значения по умолчанию. Для статических типов, если поле равно
NULL, то для экземпляров не создаётся__dict__.Если в поле
tp_dictустановлен битPy_TPFLAGS_MANAGED_DICT, тоtp_dictoffsetбудет установлено в-1, чтобы указать, что использовать это поле небезопасно.
-
initproc PyTypeObject.tp_init¶
Необязательный указатель на функцию инициализации экземпляра.
Эта функция соответствует методу
__init__()классов. Как и__init__(), можно создать экземпляр без вызова__init__(), и можно переинициализировать экземпляр, вызвав его метод__init__()ещё раз.Сигнатура функции:
int tp_init(PyObject *self, PyObject *args, PyObject *kwds);
Аргумент self – это инициализируемый экземпляр; аргументы args и kwds представляют позиционные и именованные аргументы вызова
__init__().Функция
tp_init, если она неNULL, вызывается при обычном создании экземпляра через вызов его типа, после того как функцияtp_newтипа вернула экземпляр этого типа. Если функцияtp_newвозвращает экземпляр другого типа, не являющегося подтипом исходного, функцияtp_initне вызывается; еслиtp_newвозвращает экземпляр подтипа исходного типа, вызываетсяtp_initподтипа.Возвращает
0при успехе,-1и устанавливает исключение при ошибке.Наследование:
Это поле наследуется подтипами.
По умолчанию:
Для статических типов это поле не имеет значения по умолчанию.
-
allocfunc PyTypeObject.tp_alloc¶
Необязательный указатель на функцию выделения экземпляра.
Сигнатура функции:
PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems);
Наследование:
Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными с помощью инструкции class).
По умолчанию:
Для динамических подтипов это поле всегда устанавливается в
PyType_GenericAlloc(), чтобы принудительно применять стандартную стратегию выделения памяти из кучи.Для статических подтипов
PyBaseObject_TypeиспользуетPyType_GenericAlloc(). Это рекомендуемое значение для всех статически определённых типов.
-
newfunc PyTypeObject.tp_new¶
Необязательный указатель на функцию создания экземпляра.
Сигнатура функции:
PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
Аргумент subtype – это тип создаваемого объекта; аргументы args и kwds представляют позиционные и ключевые аргументы вызова типа. Обратите внимание, что subtype не обязан совпадать с типом, чья функция
tp_newвызывается; это может быть подтип этого типа (но не произвольный тип).Функция
tp_newдолжна вызыватьsubtype->tp_alloc(subtype, nitems)для выделения памяти под объект, а затем выполнять лишь минимально необходимую инициализацию. Инициализацию, которую можно безопасно пропустить или повторить, следует помещать в обработчикtp_init. Хорошее эмпирическое правило: для неизменяемых типов вся инициализация должна выполняться вtp_new, а для изменяемых типов большую часть инициализации лучше отложить доtp_init.Флаг
Py_TPFLAGS_DISALLOW_INSTANTIATIONиспользуется для запрета создания экземпляров типа в Python.Наследование:
Это поле наследуется подтипами, за исключением статических типов, у которых
tp_baseравноNULLили&PyBaseObject_Type.По умолчанию:
Для статических типов это поле не имеет значения по умолчанию. Это означает, что если слот определён как
NULL, тип нельзя вызвать для создания новых экземпляров; предположительно, существует другой способ создания экземпляров, например фабричная функция.
-
freefunc PyTypeObject.tp_free¶
Необязательный указатель на функцию освобождения экземпляра. Её сигнатура:
void tp_free(void *self);
Инициализатор, совместимый с этой сигнатурой:
PyObject_Free().Наследование:
Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными через объявление класса).
По умолчанию:
В динамических подтипах это поле устанавливается в деаллокатор, подходящий для соответствия
PyType_GenericAlloc()и значению флагаPy_TPFLAGS_HAVE_GC.Для статических подтипов
PyBaseObject_TypeиспользуетPyObject_Del().
-
inquiry PyTypeObject.tp_is_gc¶
Необязательный указатель на функцию, вызываемую сборщиком мусора.
Сборщику мусора необходимо знать, можно ли собрать конкретный объект или нет. Обычно достаточно посмотреть на поле
tp_flagsтипа объекта и проверить бит флагаPy_TPFLAGS_HAVE_GC. Но некоторые типы содержат как статически, так и динамически выделенные экземпляры, и статически выделенные экземпляры не подлежат сборке. Такие типы должны определять эту функцию; она должна возвращать1для собираемого экземпляра и0для несобираемого. Сигнатура:int tp_is_gc(PyObject *self);
(Единственный пример этого – сами типы. Метакласс,
PyType_Type, определяет эту функцию, чтобы различать статически и динамически выделенные типы.)Наследование:
Это поле наследуется подтипами.
По умолчанию:
У этого слота нет значения по умолчанию. Если это поле равно
NULL, то в качестве функционального эквивалента используетсяPy_TPFLAGS_HAVE_GC.
-
PyObject *PyTypeObject.tp_bases¶
Кортеж базовых типов.
Это поле должно быть установлено в
NULLи считаться доступным только для чтения. Python заполнит его, когда тип будетinitialized.Для динамически создаваемых классов вместо аргумента bases из
PyType_FromSpecWithBases()можно использоватьPy_tp_basesslot. Предпочтительна форма с аргументом.Предупреждение
Множественное наследование плохо работает для статически определённых типов. Если установить
tp_basesв кортеж, Python не вызовет ошибку, но некоторые слоты будут унаследованы только от первого базового класса.Наследование:
Это поле не наследуется.
-
PyObject *PyTypeObject.tp_mro¶
Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая
object, в порядке разрешения методов (MRO).Это поле должно быть установлено в
NULLи считаться доступным только для чтения. Python заполнит его, когда тип будетinitialized.Наследование:
Это поле не наследуется; оно вычисляется заново с помощью
PyType_Ready().
-
PyObject *PyTypeObject.tp_cache¶
Не используется. Только для внутреннего использования.
Наследование:
Это поле не наследуется.
-
void *PyTypeObject.tp_subclasses¶
Коллекция подклассов. Только для внутреннего использования. Может быть недопустимым указателем.
Чтобы получить список подклассов, вызовите метод Python
__subclasses__().Изменено в версии 3.12: Для некоторых типов это поле не содержит допустимый PyObject*. Тип был изменён на void*, чтобы указать на это.
Наследование:
Это поле не наследуется.
-
PyObject *PyTypeObject.tp_weaklist¶
Голова списка слабых ссылок для слабых ссылок на этот объект типа. Не наследуется. Только для внутреннего использования.
Изменено в версии 3.12: Деталь внутренней реализации: для статических встроенных типов это всегда
NULL, даже если добавлены слабые ссылки. Вместо этого слабые ссылки для каждого хранятся вPyInterpreterState. Используйте публичный C-API или внутренний макрос_PyObject_GET_WEAKREFS_LISTPTR(), чтобы избежать этого различия.Наследование:
Это поле не наследуется.
-
destructor PyTypeObject.tp_del¶
Это поле устарело. Используйте
tp_finalizeвместо него.
-
unsigned int PyTypeObject.tp_version_tag¶
Используется для индексации кэша методов. Только для внутреннего использования.
Наследование:
Это поле не наследуется.
-
destructor PyTypeObject.tp_finalize¶
Необязательный указатель на функцию финализации экземпляра. Её сигнатура:
void tp_finalize(PyObject *self);
Если
tp_finalizeустановлен, интерпретатор вызывает его один раз при финализации экземпляра. Он вызывается либо сборщиком мусора (если экземпляр является частью изолированного цикла ссылок), либо непосредственно перед освобождением объекта. В любом случае гарантируется, что он будет вызван до попытки разорвать циклы ссылок, что обеспечивает нахождение объекта в корректном состоянии.tp_finalizeне должен изменять текущий статус исключения; поэтому рекомендуемый способ написания нетривиального финализатора:static void local_finalize(PyObject *self) { PyObject *error_type, *error_value, *error_traceback; /* Сохранить текущее исключение, если оно есть. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); /* ... */ /* Восстановить сохранённое исключение. */ PyErr_Restore(error_type, error_value, error_traceback); }
Наследование:
Это поле наследуется подтипами.
Добавлено в версии 3.4.
Изменено в версии 3.8: До версии 3.8 необходимо было установить бит флагов
Py_TPFLAGS_HAVE_FINALIZE, чтобы это поле можно было использовать. Теперь это не требуется.См. также
«Безопасная финализация объектов» (PEP 442)
-
vectorcallfunc PyTypeObject.tp_vectorcall¶
Функция vectorcall, используемая для вызовов этого объекта типа. Другими словами, она используется для реализации vectorcall для
type.__call__. Еслиtp_vectorcallравноNULL, используется реализация вызова по умолчанию с использованием__new__()и__init__().Наследование:
Это поле никогда не наследуется.
Добавлено в версии 3.9: (поле существует с версии 3.8, но используется только с версии 3.9)
-
unsigned char PyTypeObject.tp_watched¶
Внутреннее. Не использовать.
Добавлено в версии 3.12.
Статические типы¶Static Types
Традиционно типы, определяемые в коде C, являются статическими, то есть
статическая структура PyTypeObject определяется непосредственно в коде
и инициализируется с помощью PyType_Ready().
В результате получаются типы, которые ограничены по сравнению с типами, определёнными в Python.
Статические типы ограничены одним базовым классом, то есть не могут использовать множественное наследование.
Объекты статических типов (но не обязательно их экземпляры) неизменяемы. Из Python невозможно добавить или изменить атрибуты объекта типа.
Объекты статических типов разделяются между под-интерпретаторами, поэтому они не должны содержать состояние, специфичное для под-интерпретатора.
Кроме того, поскольку PyTypeObject является лишь частью Limited API в виде непрозрачной структуры, любые модули расширения, использующие статические типы, должны быть скомпилированы для конкретной минорной версии Python.
Кучные типы¶Heap Types
Альтернативой статическим типам являются кучные типы (heap-allocated types), или кучные типы (heap types) для краткости. Они очень похожи на классы, создаваемые с помощью оператора class. У кучных типов установлен флаг Py_TPFLAGS_HEAPTYPE.
Для этого заполняется структура PyType_Spec и вызывается PyType_FromSpec(), PyType_FromSpecWithBases(), PyType_FromModuleAndSpec() или PyType_FromMetaclass().
Структуры числовых объектов¶Number Object Structures
-
type PyNumberMethods¶
Эта структура содержит указатели на функции, которые объект использует для реализации числового протокола. Каждая функция используется одноимённой функцией, описанной в разделе Числовой протокол.
Вот определение структуры:
typedef struct { binaryfunc nb_add; binaryfunc nb_subtract; binaryfunc nb_multiply; binaryfunc nb_remainder; binaryfunc nb_divmod; ternaryfunc nb_power; unaryfunc nb_negative; unaryfunc nb_positive; unaryfunc nb_absolute; inquiry nb_bool; unaryfunc nb_invert; binaryfunc nb_lshift; binaryfunc nb_rshift; binaryfunc nb_and; binaryfunc nb_xor; binaryfunc nb_or; unaryfunc nb_int; void *nb_reserved; unaryfunc nb_float; binaryfunc nb_inplace_add; binaryfunc nb_inplace_subtract; binaryfunc nb_inplace_multiply; binaryfunc nb_inplace_remainder; ternaryfunc nb_inplace_power; binaryfunc nb_inplace_lshift; binaryfunc nb_inplace_rshift; binaryfunc nb_inplace_and; binaryfunc nb_inplace_xor; binaryfunc nb_inplace_or; binaryfunc nb_floor_divide; binaryfunc nb_true_divide; binaryfunc nb_inplace_floor_divide; binaryfunc nb_inplace_true_divide; unaryfunc nb_index; binaryfunc nb_matrix_multiply; binaryfunc nb_inplace_matrix_multiply; } PyNumberMethods;
Примечание
Бинарные и тернарные функции должны проверять тип всех своих операндов и выполнять необходимые преобразования (хотя бы один из операндов должен быть экземпляром определяемого типа). Если операция не определена для данных операндов, бинарные и тернарные функции должны вернуть
Py_NotImplemented; если произошла другая ошибка, они должны вернутьNULLи установить исключение.Примечание
Поле
nb_reservedвсегда должно бытьNULL. Ранее оно называлосьnb_longи было переименовано в Python 3.0.1.
-
binaryfunc PyNumberMethods.nb_add¶
-
binaryfunc PyNumberMethods.nb_subtract¶
-
binaryfunc PyNumberMethods.nb_multiply¶
-
binaryfunc PyNumberMethods.nb_remainder¶
-
binaryfunc PyNumberMethods.nb_divmod¶
-
ternaryfunc PyNumberMethods.nb_power¶
-
unaryfunc PyNumberMethods.nb_negative¶
-
unaryfunc PyNumberMethods.nb_positive¶
-
unaryfunc PyNumberMethods.nb_absolute¶
-
inquiry PyNumberMethods.nb_bool¶
-
unaryfunc PyNumberMethods.nb_invert¶
-
binaryfunc PyNumberMethods.nb_lshift¶
-
binaryfunc PyNumberMethods.nb_rshift¶
-
binaryfunc PyNumberMethods.nb_and¶
-
binaryfunc PyNumberMethods.nb_xor¶
-
binaryfunc PyNumberMethods.nb_or¶
-
unaryfunc PyNumberMethods.nb_int¶
-
void *PyNumberMethods.nb_reserved¶
-
unaryfunc PyNumberMethods.nb_float¶
-
binaryfunc PyNumberMethods.nb_inplace_add¶
-
binaryfunc PyNumberMethods.nb_inplace_subtract¶
-
binaryfunc PyNumberMethods.nb_inplace_multiply¶
-
binaryfunc PyNumberMethods.nb_inplace_remainder¶
-
ternaryfunc PyNumberMethods.nb_inplace_power¶
-
binaryfunc PyNumberMethods.nb_inplace_lshift¶
-
binaryfunc PyNumberMethods.nb_inplace_rshift¶
-
binaryfunc PyNumberMethods.nb_inplace_and¶
-
binaryfunc PyNumberMethods.nb_inplace_xor¶
-
binaryfunc PyNumberMethods.nb_inplace_or¶
-
binaryfunc PyNumberMethods.nb_floor_divide¶
-
binaryfunc PyNumberMethods.nb_true_divide¶
-
binaryfunc PyNumberMethods.nb_inplace_floor_divide¶
-
binaryfunc PyNumberMethods.nb_inplace_true_divide¶
-
unaryfunc PyNumberMethods.nb_index¶
-
binaryfunc PyNumberMethods.nb_matrix_multiply¶
-
binaryfunc PyNumberMethods.nb_inplace_matrix_multiply¶
Структуры объектов отображения¶Mapping Object Structures
-
type PyMappingMethods¶
Эта структура хранит указатели на функции, которые объект использует для реализации протокола отображения. Она содержит три члена:
-
lenfunc PyMappingMethods.mp_length¶
Эта функция используется
PyMapping_Size()иPyObject_Size()и имеет ту же сигнатуру. Этот слот может быть установлен вNULL, если у объекта нет определённой длины.
-
binaryfunc PyMappingMethods.mp_subscript¶
Эта функция используется
PyObject_GetItem()иPySequence_GetSlice()и имеет ту же сигнатуру, что иPyObject_GetItem(). Этот слот должен быть заполнен, чтобы функцияPyMapping_Check()возвращала1; в противном случае он может бытьNULL.
-
objobjargproc PyMappingMethods.mp_ass_subscript¶
Эта функция используется
PyObject_SetItem(),PyObject_DelItem(),PySequence_SetSlice()иPySequence_DelSlice(). У неё та же сигнатура, что и уPyObject_SetItem(), но v также может быть установлен вNULLдля удаления элемента. Если этот слот равенNULL, объект не поддерживает присваивание и удаление элементов.
Структуры объектов последовательностей¶Sequence Object Structures
-
type PySequenceMethods¶
Эта структура содержит указатели на функции, которые объект использует для реализации протокола последовательности.
-
lenfunc PySequenceMethods.sq_length¶
Эта функция используется
PySequence_Size()иPyObject_Size()и имеет ту же сигнатуру. Она также используется для обработки отрицательных индексов через слотыsq_itemиsq_ass_item.
-
binaryfunc PySequenceMethods.sq_concat¶
Эта функция используется
PySequence_Concat()и имеет ту же сигнатуру. Она также используется оператором+после попытки численного сложения через слотnb_add.
-
ssizeargfunc PySequenceMethods.sq_repeat¶
Эта функция используется
PySequence_Repeat()и имеет ту же сигнатуру. Она также используется оператором*после попытки численного умножения через слотnb_multiply.
-
ssizeargfunc PySequenceMethods.sq_item¶
Эта функция используется
PySequence_GetItem()и имеет ту же сигнатуру. Она также используетсяPyObject_GetItem()после попытки индексирования через слотmp_subscript. Этот слот должен быть заполнен, чтобы функцияPySequence_Check()возвращала1; в противном случае он может бытьNULL.Отрицательные индексы обрабатываются следующим образом: если слот
sq_lengthзаполнен, он вызывается, и длина последовательности используется для вычисления положительного индекса, который передаётсяsq_item. Еслиsq_lengthравноNULL, индекс передаётся функции как есть.
-
ssizeobjargproc PySequenceMethods.sq_ass_item¶
Эта функция используется
PySequence_SetItem()и имеет ту же сигнатуру. Она также используетсяPyObject_SetItem()иPyObject_DelItem()после попытки присваивания и удаления элемента через слотmp_ass_subscript. Этот слот может быть оставлен равнымNULL, если объект не поддерживает присваивание и удаление элементов.
-
objobjproc PySequenceMethods.sq_contains¶
Эта функция может использоваться
PySequence_Contains()и имеет ту же сигнатуру. Этот слот может быть оставлен равнымNULL; в этом случаеPySequence_Contains()просто проходит по последовательности, пока не найдёт совпадение.
-
binaryfunc PySequenceMethods.sq_inplace_concat¶
Эта функция используется
PySequence_InPlaceConcat()и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его. Этот слот может быть оставлен равнымNULL; в этом случаеPySequence_InPlaceConcat()будет использоватьPySequence_Concat()как запасной вариант. Она также используется расширенным присваиванием+=после попытки численного сложения на месте через слотnb_inplace_add.
-
ssizeargfunc PySequenceMethods.sq_inplace_repeat¶
Эта функция используется
PySequence_InPlaceRepeat()и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его. Этот слот может быть оставлен равнымNULL; в этом случаеPySequence_InPlaceRepeat()будет использоватьPySequence_Repeat()как запасной вариант. Она также используется расширенным присваиванием*=после попытки численного умножения на месте через слотnb_inplace_multiply.
Структуры объектов буфера¶Buffer Object Structures
-
type PyBufferProcs¶
Эта структура содержит указатели на функции, необходимые для протокола буфера. Протокол определяет, как объект-экспортёр может предоставлять свои внутренние данные объектам-потребителям.
-
getbufferproc PyBufferProcs.bf_getbuffer¶
Сигнатура этой функции:
int (PyObject *exporter, Py_buffer *view, int flags);
Обрабатывает запрос к экспортёру на заполнение представления в соответствии с флагами. За исключением пункта (3), реализация этой функции ОБЯЗАНА выполнить следующие шаги:
Проверить, может ли быть удовлетворён запрос. Если нет – вызвать
BufferError, установить view->obj вNULLи вернуть-1.Заполнить запрошенные поля.
Увеличить внутренний счётчик числа экспортов.
Установить view->obj в exporter и увеличить view->obj.
Вернуть
0.
Если экспортёр является частью цепочки или дерева поставщиков буферов, можно использовать две основные схемы:
Ре-экспорт: каждый элемент дерева выступает в роли экспортирующего объекта и устанавливает view->obj в новую ссылку на самого себя.
Перенаправление: запрос буфера перенаправляется на корневой объект дерева. Здесь view->obj будет новой ссылкой на корневой объект.
Отдельные поля представления описаны в разделе Структура буфера, правила, как экспортёр должен реагировать на конкретные запросы – в разделе Типы запросов буфера.
Вся память, на которую указывает структура
Py_buffer, принадлежит экспортёру и должна оставаться действительной, пока есть хотя бы один потребитель.format,shape,strides,suboffsetsиinternalдоступны потребителю только для чтения.PyBuffer_FillInfo()предоставляет простой способ предоставления простого байтового буфера, корректно обрабатывая все типы запросов.PyObject_GetBuffer()– это интерфейс для потребителя, который оборачивает эту функцию.
-
releasebufferproc PyBufferProcs.bf_releasebuffer¶
Сигнатура этой функции:
void (PyObject *exporter, Py_buffer *view);
Обрабатывает запрос на освобождение ресурсов буфера. Если никакие ресурсы освобождать не нужно,
PyBufferProcs.bf_releasebufferможет бытьNULL. В противном случае стандартная реализация этой функции выполнит следующие необязательные шаги:Уменьшить внутренний счётчик числа экспортов.
Если счётчик равен
0, освободить всю память, связанную с представлением.
Экспортёр ОБЯЗАН использовать поле
internalдля отслеживания ресурсов, специфичных для буфера. Гарантируется, что это поле остаётся постоянным, в то время как потребитель МОЖЕТ передавать копию исходного буфера в качестве аргумента view.Эта функция НЕ ДОЛЖНА уменьшать счётчик view->obj, поскольку это делается автоматически в
PyBuffer_Release()(такая схема полезна для разрыва циклических ссылок).PyBuffer_Release()– это интерфейс для потребителя, который оборачивает эту функцию.
Асинхронные структуры объектов¶Async Object Structures
Добавлено в версии 3.5.
-
type PyAsyncMethods¶
Эта структура содержит указатели на функции, необходимые для реализации объектов ожидаемый объект и асинхронный итератор.
Вот определение структуры:
typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; sendfunc am_send; } PyAsyncMethods;
-
unaryfunc PyAsyncMethods.am_await¶
Сигнатура этой функции:
PyObject *am_await(PyObject *self);
Возвращаемый объект должен быть итератором, т.е.
PyIter_Check()должен возвращать1для него.Этот слот может быть установлен в
NULL, если объект не является ожидаемым объектом.
-
unaryfunc PyAsyncMethods.am_aiter¶
Сигнатура этой функции:
PyObject *am_aiter(PyObject *self);
Должен возвращать объект асинхронный итератор. Подробнее см.
__anext__().Этот слот может быть установлен в
NULL, если объект не реализует протокол асинхронной итерации.
-
unaryfunc PyAsyncMethods.am_anext¶
Сигнатура этой функции:
PyObject *am_anext(PyObject *self);
Должен возвращать объект ожидаемый объект. Подробнее см.
__anext__(). Этот слот может быть установлен вNULL.
-
sendfunc PyAsyncMethods.am_send¶
Сигнатура этой функции:
PySendResult am_send(PyObject *self, PyObject *arg, PyObject **result);
Подробнее см.
PyIter_Send(). Этот слот может быть установлен вNULL.Добавлено в версии 3.10.
Определения типов слотов¶Slot Type typedefs
-
typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)¶
- Часть Stable ABI.
Назначение этой функции – разделить выделение памяти и её инициализацию. Она должна возвращать указатель на блок памяти достаточной длины для экземпляра, с подходящим выравниванием и обнулённый, но с
ob_refcnt, установленным в1, иob_type, установленным в аргумент типа. Еслиtp_itemsizeтипа не равно нулю, полеob_sizeобъекта должно быть инициализировано значением nitems, а длина выделенного блока памяти должна бытьtp_basicsize + nitems*tp_itemsize, округлённой до кратногоsizeof(void*); в противном случае nitems не используется, и длина блока должна бытьtp_basicsize.Эта функция не должна выполнять никакой другой инициализации экземпляра, включая выделение дополнительной памяти; это должно выполнять
tp_new.
-
typedef void (*destructor)(PyObject*)¶
- Часть Stable ABI.
-
typedef PyObject *(*newfunc)(PyTypeObject*, PyObject*, PyObject*)¶
- Часть Stable ABI.
См.
tp_new.
-
typedef PyObject *(*reprfunc)(PyObject*)¶
- Часть Stable ABI.
См.
tp_repr.
-
typedef PyObject *(*getattrfunc)(PyObject *self, char *attr)¶
- Часть Stable ABI.
Возвращает значение именованного атрибута для объекта.
-
typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value)¶
- Часть Stable ABI.
Устанавливает значение именованного атрибута для объекта. Аргумент value устанавливается в
NULLдля удаления атрибута.
-
typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr)¶
- Часть Stable ABI.
Возвращает значение именованного атрибута для объекта.
См.
tp_getattro.
-
typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)¶
- Часть Stable ABI.
Устанавливает значение именованного атрибута для объекта. Аргумент value устанавливается в
NULLдля удаления атрибута.См.
tp_setattro.
-
typedef PyObject *(*descrgetfunc)(PyObject*, PyObject*, PyObject*)¶
- Часть Stable ABI.
См.
tp_descr_get.
-
typedef int (*descrsetfunc)(PyObject*, PyObject*, PyObject*)¶
- Часть Stable ABI.
См.
tp_descr_set.
-
typedef Py_hash_t (*hashfunc)(PyObject*)¶
- Часть Stable ABI.
См.
tp_hash.
-
typedef PyObject *(*richcmpfunc)(PyObject*, PyObject*, int)¶
- Часть Stable ABI.
См.
tp_richcompare.
-
typedef PyObject *(*getiterfunc)(PyObject*)¶
- Часть Stable ABI.
См.
tp_iter.
-
typedef PyObject *(*iternextfunc)(PyObject*)¶
- Часть Stable ABI.
См.
tp_iternext.
-
typedef Py_ssize_t (*lenfunc)(PyObject*)¶
- Часть Stable ABI.
-
typedef int (*getbufferproc)(PyObject*, Py_buffer*, int)¶
- Часть Stable ABI начиная с версии 3.12.
-
typedef void (*releasebufferproc)(PyObject*, Py_buffer*)¶
- Часть Stable ABI начиная с версии 3.12.
-
typedef PyObject *(*unaryfunc)(PyObject*)¶
- Часть Stable ABI.
-
typedef PyObject *(*binaryfunc)(PyObject*, PyObject*)¶
- Часть Stable ABI.
-
typedef PyObject *(*ssizeargfunc)(PyObject*, Py_ssize_t)¶
- Часть Stable ABI.
-
typedef int (*ssizeobjargproc)(PyObject*, Py_ssize_t, PyObject*)¶
- Часть Stable ABI.
-
typedef int (*objobjproc)(PyObject*, PyObject*)¶
- Часть Stable ABI.
-
typedef int (*objobjargproc)(PyObject*, PyObject*, PyObject*)¶
- Часть Stable ABI.
Примеры¶Examples
Ниже приведены простые примеры определений типов Python. Они включают распространённые варианты использования, с которыми можно столкнуться. Некоторые демонстрируют сложные граничные случаи. За дополнительными примерами, практической информацией и учебным пособием обращайтесь к Defining Extension Types: Tutorial и Defining Extension Types: Assorted Topics.
Базовый статический тип:
typedef struct {
PyObject_HEAD
const char *data;
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject),
.tp_doc = PyDoc_STR("My objects"),
.tp_new = myobj_new,
.tp_dealloc = (destructor)myobj_dealloc,
.tp_repr = (reprfunc)myobj_repr,
};
Также можно встретить старый код (особенно в кодовой базе CPython) с более многословным инициализатором:
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"mymod.MyObject", /* tp_name */
sizeof(MyObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)myobj_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
(reprfunc)myobj_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
PyDoc_STR("My objects"), /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
myobj_new, /* tp_new */
};
Тип, поддерживающий слабые ссылки, словари экземпляров и хеширование:
typedef struct {
PyObject_HEAD
const char *data;
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject),
.tp_doc = PyDoc_STR("My objects"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT |
Py_TPFLAGS_MANAGED_WEAKREF,
.tp_new = myobj_new,
.tp_traverse = (traverseproc)myobj_traverse,
.tp_clear = (inquiry)myobj_clear,
.tp_alloc = PyType_GenericNew,
.tp_dealloc = (destructor)myobj_dealloc,
.tp_repr = (reprfunc)myobj_repr,
.tp_hash = (hashfunc)myobj_hash,
.tp_richcompare = PyBaseObject_Type.tp_richcompare,
};
Подкласс str, который нельзя наследовать и который нельзя вызывать
для создания экземпляров (например, используется отдельная фабричная функция) с помощью
флага Py_TPFLAGS_DISALLOW_INSTANTIATION:
typedef struct {
PyUnicodeObject raw;
char *extra;
} MyStr;
static PyTypeObject MyStr_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyStr",
.tp_basicsize = sizeof(MyStr),
.tp_base = NULL, // устанавливается в &PyUnicode_Type при инициализации модуля
.tp_doc = PyDoc_STR("my custom str"),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
.tp_repr = (reprfunc)myobj_repr,
};
Простейший статический тип с экземплярами фиксированной длины:
typedef struct {
PyObject_HEAD
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
};
Простейший статический тип с экземплярами переменной длины:
typedef struct {
PyObject_VAR_HEAD
const char *data[1];
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
.tp_basicsize = sizeof(MyObject) - sizeof(char *),
.tp_itemsize = sizeof(char *),
};
Эта страница – перевод. Оригинал на английском – docs.python.org. Нашли неточность? Сообщите нам.