Объекты типов
Возможно, одной из самых важных структур системы объектов 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__ | ||
Определения типов слотов
typedef | Типы параметров | Тип возвращаемого значения |
|---|---|---|
| ||
| void | |
void * | void | |
int | ||
| ||
int | ||
|
| |
| ||
int | ||
| ||
int | ||
| ||
int | ||
| Py_hash_t | |
| ||
|
| |
|
| |
| ||
int | ||
void | ||
| int | |
| ||
| ||
| ||
| ||
int | ||
int | ||
int |
См. Определения типов слотов ниже для получения более подробной информации.
Определение 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_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
-
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); }Наследование:
Это поле наследуется подтипами.
-
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.
-
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его экземпляров рассматривается как ссылка на тип, и объект типа INCREF’ится при создании нового экземпляра и DECREF’ится при уничтожении экземпляра (это не относится к экземплярам подтипов; только тип, на который ссылается поле ob_type экземпляра, получает INCREF’ить или DECREF’ить). Типы кучи также должны поддерживать сборку мусора, так как они могут образовывать цикл ссылок со своим собственным объектом модуля.Наследование:
???
-
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 -
Этот бит указывает, что экземпляры класса имеют атрибут
__dict__, и что пространство для словаря управляется виртуальной машиной.Если этот флаг установлен,
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 -
Эти флаги используются функциями, такими как
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 и, следовательно, не может быть частью цикла ссылок.С другой стороны, даже если вам известно, что член никогда не может быть частью цикла, в качестве средства отладки вы можете посетить его, чтобы функция
gcмодуляget_referents()включала его.Предупреждение
При реализации
tp_traverseнеобходимо посетить только те члены, которые владеет экземпляр (имея сильные ссылки на них). Например, если объект поддерживает слабые ссылки через слотtp_weaklist, указатель, поддерживающий связанный список (на что указывает tp_weaklist), не должен посещаться, так как экземпляр не владеет напрямую слабыми ссылками на себя (список weakreference предназначен для поддержки механизма слабых ссылок, но у экземпляра нет сильной ссылки на элементы внутри него, так как они могут быть удалены, даже если экземпляр все еще жив).Обратите внимание, что
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()выполняет операции в безопасном порядке.Обратите внимание, что функция
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 -
Необязательный указатель на статический массив, завершаемый нулём, структур
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()со словарем C-API или иным образом изменятьtp_dict.
-
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_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);
Наследование:
Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными оператором класса).
Значение по умолчанию:
Для динамических подтипов это поле всегда установлено в
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, в порядке разрешения методов.Это поле должно быть установлено в
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); }Также обратите внимание, что в Python со сборкой мусора
tp_deallocможет быть вызван из любого потока Python, а не только из потока, который создал объект (если объект попадет в цикл ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Это не проблема для вызовов API Python, так как поток, в котором вызывается tp_dealloc, будет владеть глобальной блокировкой интерпретатора (GIL). Однако, если разрушаемый объект, в свою очередь, разрушает объекты из какой-либо другой библиотеки C или C++, следует позаботиться о том, чтобы разрушение этих объектов в потоке, который вызвал tp_dealloc, не нарушало никаких предположений библиотеки.Наследование:
Это поле наследуется подтипами.
Добавлена в версии 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().
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/c-api/typeobj.html