Объекты типов
Возможно, одной из самых важных структур системы объектов Python является структура, определяющая новый тип: структура PyTypeObject. Объекты типов могут обрабатываться с помощью любых функций PyObject_* или PyType_*, но не предоставляют много интересного для большинства приложений Python. Эти объекты фундаментальны для поведения объектов, поэтому они очень важны для самого интерпретатора и любого модуля расширения, реализующего новые типы.
Объекты типов довольно велики по сравнению с большинством стандартных типов. Причина этого размера в том, что каждый объект типа хранит большое количество значений, в основном указатели на C-функции, каждая из которых реализует небольшую часть функциональности типа. Поля объекта типа подробно рассматриваются в этом разделе. Поля будут описаны в порядке их появления в структуре.
Помимо следующей краткой справки, раздел Примеры предоставляет наглядное представление о значении и использовании PyTypeObject.
Быстрый справочник
"tp slots"
Слоты объекта PyTypeObject [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 | ||||||
подслоты
Разъем | специальные методы | |
|---|---|---|
__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 | ||
|
| |
| ||
int | ||
| ||
int | ||
| ||
int | ||
| Py_hash_t | |
| ||
|
| |
|
| |
| ||
int | ||
void | ||
| int | |
| ||
| ||
| ||
| ||
int | ||
int | ||
int |
См. Slot Type typedefs ниже для получения более подробной информации.
Определение PyTypeObject
Определение структуры PyTypeObject можно найти в Include/object.h. Для удобства ссылки приводится определение, содержащееся там:
typedef struct _typeobject {
PyObject_VAR_HEAD
const char *tp_name; /* For printing, in format "<module>.<name>" */
Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
Py_ssize_t tp_vectorcall_offset;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
or tp_reserved (Python 3) */
reprfunc tp_repr;
/* Method suites for standard classes */
PyNumberMethods *tp_as_number;
PySequenceMethods *tp_as_sequence;
PyMappingMethods *tp_as_mapping;
/* More standard operations (here for binary compatibility) */
hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;
/* Functions to access object as input/output buffer */
PyBufferProcs *tp_as_buffer;
/* Flags to define presence of optional/expanded features */
unsigned long tp_flags;
const char *tp_doc; /* Documentation string */
/* Assigned meaning in release 2.0 */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
/* Assigned meaning in release 2.1 */
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
Py_ssize_t tp_weaklistoffset;
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
// Strong reference on a heap type, borrowed reference on a static type
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; /* Low-level free-memory routine */
inquiry tp_is_gc; /* For PyObject_IS_GC */
PyObject *tp_bases;
PyObject *tp_mro; /* method resolution order */
PyObject *tp_cache;
PyObject *tp_subclasses;
PyObject *tp_weaklist;
destructor tp_del;
/* Type attribute cache version tag. Added in version 2.6 */
unsigned int tp_version_tag;
destructor tp_finalize;
vectorcallfunc tp_vectorcall;
/* bitset of which type-watchers care about this type */
unsigned char tp_watched;
} PyTypeObject;
Слоты PyObject
Структура объекта типа расширяет структуру PyVarObject. Поле ob_size используется для динамических типов (созданных type_new(), обычно вызываемых из оператора класса). Обратите внимание, что PyType_Type (метатип) инициализирует tp_itemsize, что означает, что его экземпляры (объекты типов) должны иметь поле ob_size.
-
Py_ssize_t PyObject.ob_refcnt -
Часть Стабильной ABI.
Это счетчик ссылок объекта типа, инициализированный значением
1макросомPyObject_HEAD_INIT. Обратите внимание, что для статически выделенных объектов типа экземпляры типа (объекты, чьеob_typeуказывает обратно на тип) не считаются ссылками. Но для динамически выделенных объектов типа экземпляры считаются ссылками.Наследование:
Это поле не наследуется подтипами.
-
PyTypeObject *PyObject.ob_type -
Часть Стабильной ABI.
Это тип типа, другими словами, его метатип. Он инициализируется аргументом макроса
PyObject_HEAD_INIT, и его значение обычно должно быть&PyType_Type. Однако для динамически загружаемых модулей расширения, которые должны быть пригодны для использования в Windows (по крайней мере), компилятор жалуется, что это не допустимое начальное значение. Поэтому соглашение состоит в том, чтобы передатьNULLмакросуPyObject_HEAD_INITи явно инициализировать это поле в начале функции инициализации модуля, прежде чем выполнять какие-либо другие действия. Обычно это делается так:Foo_Type.ob_type = &PyType_Type;
Это должно выполняться до создания каких-либо экземпляров типа.
PyType_Ready()проверяет, равно лиob_typeNULL, и если да, то инициализирует его значением поляob_typeбазового класса.PyType_Ready()не изменит это поле, если оно отлично от нуля.Наследование:
Это поле наследуется подтипами.
Слоты PyVarObject
-
Py_ssize_t PyVarObject.ob_size -
Часть Стабильной ABI.
Для статически выделенных объектов типа это значение должно быть равно нулю. Для динамически выделенных объектов типа это поле имеет специальное внутреннее значение.
Наследование:
Это поле не наследуется подтипами.
Слот PyTypeObject
Каждый слот имеет раздел, описывающий наследование. Если PyType_Ready() может установить значение, когда поле установлено в NULL , то также будет раздел «Значение по умолчанию». (Обратите внимание, что многие поля, устанавливаемые в PyBaseObject_Type и PyType_Type, фактически действуют как значения по умолчанию.)
-
const char *PyTypeObject.tp_name -
Указатель на строку с завершающим нулем, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов она должна содержать только имя типа. Если модуль является подмодулем пакета, полное имя пакета является частью полного имени модуля. Например, тип с именем
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.Для типа с экземплярами переменной длины экземпляры должны иметь поле
ob_size, а размер экземпляра составляетtp_basicsizeплюс N разtp_itemsize, где N — «длина» объекта. Значение N обычно хранится в полеob_sizeэкземпляра. Есть исключения: например, целые числа используют отрицательноеob_sizeдля обозначения отрицательного числа, а N равноabs(ob_size)там. Кроме того, наличие поляob_sizeв структуре экземпляра не означает, что структура экземпляра имеет переменную длину (например, структура типа списка имеет экземпляры фиксированной длины, но эти экземпляры имеют осмысленное полеob_size).Базовый размер включает поля в экземпляре, объявленные макросом
PyObject_HEADилиPyObject_VAR_HEAD(в зависимости от используемой для объявления структуры экземпляра), и это в свою очередь включает поля_ob_prevи_ob_next, если они присутствуют. Это означает, что единственный правильный способ получить инициализатор дляtp_basicsizeзаключается в использовании оператораsizeofдля структуры, используемой для объявления структуры экземпляра. Базовый размер не включает размер заголовка GC.Замечание об выравнивании: если переменные элементы требуют определенного выравнивания, это должно учитываться значением
tp_basicsize. Пример: предположим, что тип реализует массивdouble.tp_itemsizeравноsizeof(double). Задача программиста — убедиться, чтоtp_basicsizeявляется кратнымsizeof(double)(предполагая, что это требование к выравниванию дляdouble).Для любого типа с экземплярами переменной длины это поле не должно быть
NULL.Наследование:
Эти поля наследуются подтипами отдельно. Если базовый тип имеет не нулевое
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); // free references and buffers here tp->tp_free(self); Py_DECREF(tp); }Предупреждение
В Python со сбором мусора
tp_deallocможет вызываться из любого потока Python, а не только из потока, который создал объект (если объект становится частью цикла ссылок, этот цикл может быть собран сборкой мусора в любом потоке). Это не проблема для вызовов Python API, так как поток, в котором вызывается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 -
Указатель на дополнительную структуру, содержащую поля, относящиеся только к объектам, реализующим протоколы awaitable и асинхронный итератор на уровне 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.Значение по умолчанию:
PyBaseObject_TypeиспользуетPyObject_GenericHash().
-
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 -
Указатель на дополнительную структуру, содержащую поля, относящиеся только к объектам, реализующим интерфейс буфера. Эти поля документированы в Структуры объекта буфера.
Наследование:
Поле
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его экземпляров считается ссылкой на тип, и объект типа увеличивает счётчик ссылок при создании нового экземпляра и уменьшает его при уничтожении экземпляра (это не относится к экземплярам подтипов; только тип, на который ссылается поле ob_type экземпляра, получает увеличение или уменьшение счётчика ссылок). Типы кучи также должны поддерживать сборку мусора, так как они могут образовывать цикл ссылок со своим собственным объектом модуля.Наследование:
???
-
Py_TPFLAGS_BASETYPE -
Этот бит устанавливается, когда тип может использоваться в качестве базового типа другого типа. Если этот бит сброшен, тип не может быть подтипом (похоже на «final» класс в 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 -
Этот бит указывает, что экземпляры класса имеют атрибут
~object.__dict__, и что место для словаря управляется виртуальной машиной.Если этот флаг установлен, должен быть установлен и флаг
Py_TPFLAGS_HAVE_GC.Функция перехода типа должна вызывать
PyObject_VisitManagedDict(), а функция очистки должна вызыватьPyObject_ClearManagedDict().Добавлен в версии 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 -
Эти флаги используются функциями, такими как
PyLong_Check(), для быстрого определения, является ли тип подклассом встроенного типа; такие специфические проверки выполняются быстрее, чем общая проверка, например,PyObject_IsInstance(). Пользовательские типы, которые наследуют от встроенных типов, должны иметь соответствующее значениеtp_flags, в противном случае код, взаимодействующий с такими типами, будет вести себя по-разному в зависимости от того, какой вид проверки используется.
-
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()Предупреждение
Этот флаг присутствует в заголовочных файлах, но не используется. Он будет удален в будущих версиях CPython
-
-
const char *PyTypeObject.tp_doc -
Необязательная ссылка на строку C с завершающим нулём, содержащая строку документации для этого объекта типа. Она доступна как атрибут
__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 и поэтому не может быть частью цикла ссылок.С другой стороны, даже если вы знаете, что член никогда не может быть частью цикла, для отладки вы можете посетить его, чтобы функция модуля
gcget_referents()включала его.Типы кучи (
Py_TPFLAGS_HEAPTYPE) должны посещать свой тип следующим образом:Py_VISIT(Py_TYPE(self));
Это необходимо только начиная с Python 3.9. Чтобы поддержать Python 3.8 и более ранние версии, эта строка должна быть условной:
#if PY_VERSION_HEX >= 0x03090000 Py_VISIT(Py_TYPE(self)); #endifЕсли бит
Py_TPFLAGS_MANAGED_DICTустановлен в полеtp_flags, функция обхода должна вызватьPyObject_VisitManagedDict()так:PyObject_VisitManagedDict((PyObject*)self, visit, arg);
Предупреждение
При реализации
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. Например, тип кортежа не реализует функцию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-кода (из-за финализаторов или обратных вызовов weakref, связанных с содержащимся объектом). Если такой код может снова сослаться на self, важно, чтобы указатель на содержащийся объект былNULLв этот момент, чтобы self знал, что содержащийся объект больше использовать нельзя. МакросPy_CLEAR()выполняет операции в безопасном порядке.Если бит
Py_TPFLAGS_MANAGED_DICTустановлен в полеtp_flags, функция обхода должна вызыватьPyObject_ClearManagedDict()следующим образом:PyObject_ClearManagedDict((PyObject*)self);
Обратите внимание, что
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 (например, это могут быть целочисленные или плавающие значения C). Третий аргумент указывает запрашиваемую операцию, как для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_ssize_t PyTypeObject.tp_weaklistoffset -
Хотя это поле всё ещё поддерживается,
Py_TPFLAGS_MANAGED_WEAKREFследует использовать вместо него, если это возможно.Если экземпляры этого типа могут быть слабо ссылаемыми, это поле больше нуля и содержит смещение в структуре экземпляра для заголовка списка слабых ссылок (игнорируя заголовок сборщика мусора, если он есть); это смещение используется функциями
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 -
Необязательный указатель на статический
NULL-завершённый массив структурPyMethodDef, объявляющих обычные методы этого типа.Для каждой записи в массиве добавляется запись в словарь типа (см.
tp_dictниже), содержащая описатель метода.Наследование:
Это поле не наследуется подтипами (методы наследуются через другой механизм).
-
struct PyMemberDef *PyTypeObject.tp_members -
Необязательный указатель на статический
NULL-завершённый массив структурPyMemberDef, объявляющих обычные данные членов (полей или слотов) экземпляров этого типа.Для каждой записи в массиве добавляется запись в словарь типа (см.
tp_dictниже), содержащая описатель члена.Наследование:
Это поле не наследуется подтипами (члены наследуются через другой механизм).
-
struct PyGetSetDef *PyTypeObject.tp_getset -
Необязательный указатель на статический
NULL-завершённый массив структурPyGetSetDef, объявляющих вычисляемые атрибуты экземпляров этого типа.Для каждой записи в массиве добавляется запись в словарь типа (см.
tp_dictниже), содержащая описатель getset.Наследование:
Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).
-
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 -
Необязательный указатель на функцию «получения описателя».
Сигнатура функции:
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_WEAKREFиtp_dictoffset.Наследование:
Это поле наследуется подтипами. Подтип не должен переопределять это смещение; это может быть небезопасно, если код C попытается получить доступ к словарю по предыдущему смещению. Для правильной поддержки наследования используйте
Py_TPFLAGS_MANAGED_DICT.Значение по умолчанию:
Этот слот не имеет значения по умолчанию. Для статических типов, если поле
NULL, то для экземпляров не создаётся__dict__.Если бит
Py_TPFLAGS_MANAGED_DICTустановлен в полеtp_flags, то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);
Наследование:
Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипы, созданные инструкцией класса).
Значение по умолчанию:
Для динамических подтипов это поле всегда установлено в
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.Для динамически созданных классов можно использовать
Py_tp_basesslotвместо аргумента bases функцииPyType_FromSpecWithBases(). Рекомендуется использовать форму с аргументами.Предупреждение
Множественное наследование не работает хорошо для статически определённых типов. Если вы установите
tp_basesв кортеж, Python не выдаст ошибку, но некоторые слоты будут унаследованы только от первого базового типа.Наследование:
Это поле не наследуется.
-
PyObject *PyTypeObject.tp_mro -
Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая
object, в порядке разрешения методов.Это поле должно быть установлено в
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; /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); /* ... */ /* Restore the saved exception. */ 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.
Статические типы
Традиционно типы, определённые в коде на C, являются статическими, то есть статическая структура PyTypeObject определяется непосредственно в коде и инициализируется с помощью PyType_Ready().
Это приводит к типам, которые ограничены по сравнению с типами, определёнными в Python:
- Статические типы ограничены одним базовым типом, т.е. они не могут использовать множественное наследование.
- Объекты статических типов (но не обязательно их экземпляры) являются неизменяемыми. Из Python невозможно добавить или изменить атрибуты объекта типа.
- Объекты статических типов общие для под-интерпретаторов, поэтому они не должны содержать состояния, специфичного для под-интерпретаторов.
Также, так как PyTypeObject является лишь частью ограниченного API как непрозрачная структура, любые модули расширения, использующие статические типы, должны быть скомпилированы для определённой версии Python.
Типы кучи
Альтернатива статическим типам — это типы, выделенные в куче, или коротко типы кучи, которые тесно соответствуют классам, созданным в Python с помощью оператора class. У типов кучи установлен флаг Py_TPFLAGS_HEAPTYPE.
Это делается путём заполнения структуры PyType_Spec и вызова PyType_FromSpec(), PyType_FromSpecWithBases(), PyType_FromModuleAndSpec() или PyType_FromMetaclass().
Структуры объекта Число
-
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
Структуры объекта Картирования
-
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, объект не поддерживает присвоение и удаление элементов.
Структуры объектов последовательностей
-
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.
Структуры объектов буфера
-
type PyBufferProcs -
Эта структура содержит указатели на функции, необходимые для протокола буфера. Протокол определяет, как объект-экспортер может предоставить свои внутренние данные объектам-потребителям.
-
getbufferproc PyBufferProcs.bf_getbuffer -
Подпись этой функции:
int (PyObject *exporter, Py_buffer *view, int flags);
Обработать запрос к экспортеру для заполнения view в соответствии со спецификацией flags. За исключением пункта (3), реализация этой функции ДОЛЖНА выполнить следующие действия:
- Проверить, может ли быть выполнен запрос. Если нет, выбросить исключение
BufferError, установить view->obj вNULLи вернуть-1. - Заполнить запрашиваемые поля.
- Увеличить внутренний счётчик числа экспортов.
- Установить view->obj на экспортер и увеличить view->obj.
- Вернуть
0.
Если экспортер является частью цепочки или дерева поставщиков буфера, можно использовать две основные схемы:
- Реэкспорт: Каждый член дерева действует как экспортирующий объект и устанавливает view->obj на новую ссылку на себя.
- Перенаправление: Запрос на буфер перенаправляется на корневой объект дерева. Здесь view->obj будет новой ссылкой на корневой объект.
Индивидуальные поля view описаны в разделе Структура буфера, правила, как экспортер должен реагировать на конкретные запросы, находятся в разделе Типы запросов к буферу.
Вся память, на которую указывают поля в структуре
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, освободить всю память, связанную с view.
Экспортер ДОЛЖЕН использовать поле
internal, чтобы отслеживать ресурсы, специфичные для буфера. Это поле гарантированно остаётся постоянным, в то время как потребитель МОЖЕТ передать копию исходного буфера в качестве аргумента view.Эта функция НЕ ДОЛЖНА уменьшать view->obj, так как это делается автоматически в
PyBuffer_Release()(эта схема полезна для разрыва циклов ссылок).PyBuffer_Release()является интерфейсом для потребителя, который оборачивает эту функцию.
Структуры асинхронных объектов
Добавлен в версии 3.5.
-
type PyAsyncMethods -
Эта структура содержит указатели на функции, необходимые для реализации объектов awaitable и асинхронного итератора.
Вот определение структуры:
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если объект не является awaitable.
-
unaryfunc PyAsyncMethods.am_aiter -
Подпись этой функции:
PyObject *am_aiter(PyObject *self);
Должен вернуть объект асинхронного итератора. Подробности см. в
__anext__().Этот слот может быть установлен в
NULLесли объект не реализует протокол асинхронной итерации.
-
unaryfunc PyAsyncMethods.am_anext -
Подпись этой функции:
PyObject *am_anext(PyObject *self);
Должен вернуть объект awaitable. Подробности см. в
__anext__(). Этот слот может быть установлен вNULL.
-
sendfunc PyAsyncMethods.am_send -
Подпись этой функции:
PySendResult am_send(PyObject *self, PyObject *arg, PyObject **result);
См.
PyIter_Send()для деталей. Этот слот может быть установлен вNULL.Добавлен в версии 3.10.
Определения типов слотов
-
typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems) -
Часть Стабильной 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*) - Часть Стабильной ABI.
-
typedef void (*freefunc)(void*) -
См.
tp_free.
-
typedef PyObject *(*newfunc)(PyObject*, PyObject*, PyObject*) -
Часть Стабильной ABI.
См.
tp_new.
-
typedef int (*initproc)(PyObject*, PyObject*, PyObject*) -
Часть Стабильной ABI.
См.
tp_init.
-
typedef PyObject *(*reprfunc)(PyObject*) -
Часть Стабильной ABI.
См.
tp_repr.
-
typedef PyObject *(*getattrfunc)(PyObject *self, char *attr) -
Часть Стабильной ABI.
Возвращает значение заданного атрибута для объекта.
-
typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value) -
Часть Стабильной ABI.
Устанавливает значение заданного атрибута для объекта. Аргумент value устанавливается в
NULLдля удаления атрибута.
-
typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr) -
Часть Стабильной ABI.
Возвращает значение заданного атрибута для объекта.
См.
tp_getattro.
-
typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value) -
Часть Стабильной ABI.
Устанавливает значение заданного атрибута для объекта. Аргумент value устанавливается в
NULLдля удаления атрибута.См.
tp_setattro.
-
typedef PyObject *(*descrgetfunc)(PyObject*, PyObject*, PyObject*) -
Часть Стабильной ABI.
См.
tp_descr_get.
-
typedef int (*descrsetfunc)(PyObject*, PyObject*, PyObject*) -
Часть Стабильной ABI.
См.
tp_descr_set.
-
typedef Py_hash_t (*hashfunc)(PyObject*) -
Часть Стабильной ABI.
См.
tp_hash.
-
typedef PyObject *(*richcmpfunc)(PyObject*, PyObject*, int) -
Часть Стабильной ABI.
См.
tp_richcompare.
-
typedef PyObject *(*getiterfunc)(PyObject*) -
Часть Стабильной ABI.
См.
tp_iter.
-
typedef PyObject *(*iternextfunc)(PyObject*) -
Часть Стабильной ABI.
См.
tp_iternext.
-
typedef Py_ssize_t (*lenfunc)(PyObject*) - Часть Стабильной ABI.
-
typedef int (*getbufferproc)(PyObject*, Py_buffer*, int) - Часть Стабильной ABI с версии 3.12.
-
typedef void (*releasebufferproc)(PyObject*, Py_buffer*) - Часть Стабильной ABI с версии 3.12.
-
typedef PyObject *(*unaryfunc)(PyObject*) - Часть Стабильной ABI.
-
typedef PyObject *(*binaryfunc)(PyObject*, PyObject*) - Часть Стабильной ABI.
-
typedef PySendResult (*sendfunc)(PyObject*, PyObject*, PyObject**) -
См.
am_send.
-
typedef PyObject *(*ternaryfunc)(PyObject*, PyObject*, PyObject*) - Часть Стабильной ABI.
-
typedef PyObject *(*ssizeargfunc)(PyObject*, Py_ssize_t) - Часть Стабильной ABI.
-
typedef int (*ssizeobjargproc)(PyObject*, Py_ssize_t, PyObject*) - Часть Стабильной ABI.
-
typedef int (*objobjproc)(PyObject*, PyObject*) - Часть Стабильной ABI.
-
typedef int (*objobjargproc)(PyObject*, PyObject*, PyObject*) - Часть Стабильной ABI.
Примеры
Ниже приведены простые примеры определений типов Python. Они включают в себя распространенное использование, с которым вы можете столкнуться. Некоторые демонстрируют сложные частные случаи. Для получения более подробных примеров, практической информации и руководства см. Определение типов расширений: Руководство и Определение типов расширений: Различные темы.
Базовый статический тип:
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 */
};
Тип, поддерживающий weakrefs, словари экземпляров и хеширование:
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, // set to &PyUnicode_Type in module init
.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 *),
};
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/c-api/typeobj.html