Типовые объекты¶
Возможно, одной из самых важных структур объектной системы Python является структура, определяющая новый тип: структура PyTypeObject
. С объектами типа можно работать с помощью любой из функций PyObject_* или PyType_*, но они не предлагают ничего интересного для большинства приложений Python. Эти объекты являются фундаментальными для того, как ведут себя объекты, поэтому они очень важны для самого интерпретатора и для любого модуля расширения, реализующего новые типы.
Объекты типов довольно велики по сравнению с большинством стандартных типов. Причина такого размера заключается в том, что каждый объект типа хранит большое количество значений, в основном указателей функций языка Си, каждое из которых реализует небольшую часть функциональности типа. В этом разделе подробно рассматриваются поля объекта типа. Поля будут описаны в том порядке, в котором они встречаются в структуре.
В дополнение к следующему краткому справочнику, раздел Примеры дает представление о значении и использовании 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 |
|||
% |
||||||
беззнаковая длина |
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 |
||||
__база__ |
X |
|||||
|
__диктат__ |
? |
||||
__get__ |
X |
|||||
__set__, __delete__ |
X |
|||||
X |
? |
|||||
__init__ |
X |
X |
X |
|||
X |
? |
? |
||||
__new__ |
X |
X |
? |
? |
||
X |
X |
? |
? |
|||
X |
X |
|||||
|
__базы__ |
~ |
||||
|
__mro__ |
~ |
||||
[ |
|
|||||
|
__подклассы__. |
|||||
|
||||||
( |
||||||
unsigned int |
||||||
__del__ |
X |
|||||
- 1
Имя слота в круглых скобках означает, что оно (фактически) устарело. Имена в угловых скобках следует рассматривать как доступные только для чтения. Имена в квадратных скобках предназначены только для внутреннего использования. «<R>» (в качестве префикса) означает, что поле является обязательным (должно быть не``NULL``).
- 2
Колонки:
«O «: установить на
PyBaseObject_Type
.«T «: установить на
PyType_Type
.«D «: по умолчанию (если слот установлен на
NULL
)X - PyType_Ready sets this value if it is NULL ~ - PyType_Ready always sets this value (it should be NULL) ? - PyType_Ready may set this value depending on other slots Also see the inheritance column ("I").
«I «: наследство
X - type slot is inherited via *PyType_Ready* if defined with a *NULL* value % - the slots of the sub-struct are inherited individually G - inherited, but only in combination with other slots; see the slot's description ? - it's complicated; see the slot's description
Обратите внимание, что некоторые слоты эффективно наследуются через обычную цепочку поиска атрибутов.
подслоты¶
Слот |
специальные методы |
|
---|---|---|
__ожидать__. |
||
__aiter__ |
||
__anext__ |
||
__add__ __radd__ |
||
__iadd__ |
||
__sub__ __rsub__ |
||
__isub__ |
||
__мул__ __рмул__ |
||
__imul__ |
||
__mod__ __rmod__ |
||
__imod__ |
||
__divmod__ __rdivmod__ |
||
__pow__ __rpow__ |
||
__ipow__ |
||
__neg__ |
||
__pos__ |
||
__abs__ |
||
__bool__ |
||
__инвертировать__. |
||
__lshift__ __rlshift__ |
||
__ilshift__ |
||
__rrshift__ __rrshift__ |
||
__irshift__ |
||
__and__ __rand__ |
||
__iand__ |
||
__xor__ __rxor__ |
||
__ixor__. |
||
__ор__ __рор__ |
||
__ior__ |
||
__int__ |
||
void * |
||
__float__ |
||
__floordiv__ |
||
__ifloordiv__ |
||
__truediv__ |
||
__itruediv__ |
||
__index__ |
||
__matmul__ __rmatmul__ |
||
__imatmul__ |
||
__len__ |
||
__getitem__ |
||
__setitem__, __delitem__ |
||
__len__ |
||
__add__ |
||
__mul__ |
||
__getitem__ |
||
__setitem__ __delitem__ |
||
__содержит__. |
||
__iadd__ |
||
__imul__ |
||
типы слотов¶
typedef |
Типы параметров |
Тип возврата |
---|---|---|
|
||
void * |
void |
|
void * |
void |
|
int |
||
|
||
int |
||
|
|
|
PyObject *const char *
|
|
|
int |
||
|
||
int |
||
|
||
int |
||
|
Py_hash_t |
|
|
||
|
|
|
|
|
|
|
||
int |
||
void |
||
void * |
int |
|
PyObject * |
|
|
|
||
|
||
|
||
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;
} PyTypeObject;
Слоты PyObject¶
Структура объекта типа расширяет структуру PyVarObject
. Поле ob_size
используется для динамических типов (создаваемых type_new()
, обычно вызываемых из оператора class). Обратите внимание, что PyType_Type
(метатип) инициализирует tp_itemsize
, что означает, что его экземпляры (т.е. объекты типа) должны иметь поле ob_size
.
-
Py_ssize_t
PyObject
.
ob_refcnt
¶ - Part of the Stable ABI.
Это счетчик ссылок объекта типа, инициализированный макросом
1
в значениеPyObject_HEAD_INIT
. Обратите внимание, что для statically allocated type objects экземпляры типа (объекты, чейob_type
указывает обратно на тип) не считаются ссылками. Но для dynamically allocated type objects экземпляры до считаются ссылками.Наследственность:
Это поле не наследуется подтипами.
-
PyTypeObject *
PyObject
.
ob_type
¶ - Part of the Stable ABI.
Это тип типа, другими словами, его метатип. Он инициализируется аргументом макроса
PyObject_HEAD_INIT
, и его значение обычно должно быть&PyType_Type
. Однако для динамически загружаемых модулей расширения, которые должны быть пригодны для использования в Windows (по крайней мере), компилятор жалуется, что это недопустимый инициализатор. Поэтому принято передаватьNULL
в макросPyObject_HEAD_INIT
и инициализировать это поле явно в начале функции инициализации модуля, прежде чем делать что-либо еще. Обычно это делается следующим образом:Foo_Type.ob_type = &PyType_Type;
Это должно быть сделано до создания каких-либо экземпляров типа.
PyType_Ready()
проверяет, является лиob_type
NULL
, и если да, инициализирует его полемob_type
базового класса.PyType_Ready()
не изменяет это поле, если оно ненулевое.Наследственность:
Это поле наследуется подтипами.
-
PyObject *
PyObject
.
_ob_next
¶ -
PyObject *
PyObject
.
_ob_prev
¶ Эти поля присутствуют только тогда, когда определен макрос
Py_TRACE_REFS
(см.configure --with-trace-refs option
).Об их инициализации в
NULL
позаботится макросPyObject_HEAD_INIT
. Для statically allocated objects эти поля всегда остаютсяNULL
. Для dynamically allocated objects эти два поля используются для связывания объекта в двусвязный список всех живых объектов на куче.Это может быть использовано для различных целей отладки; в настоящее время используются только функция
sys.getobjects()
и для печати объектов, которые все еще живы в конце выполнения, когда установлена переменная окруженияPYTHONDUMPREFS
.Наследственность:
Эти поля не наследуются подтипами.
Слоты PyVarObject¶
-
Py_ssize_t
PyVarObject
.
ob_size
¶ - Part of the Stable ABI.
Для statically allocated type objects это поле должно быть инициализировано нулем. Для dynamically allocated type objects это поле имеет специальное внутреннее значение.
Наследственность:
Это поле не наследуется подтипами.
Слоты PyTypeObject¶
Каждый слот имеет раздел, описывающий наследование. Если PyType_Ready()
может устанавливать значение, когда поле установлено на NULL
, то будет также раздел «По умолчанию». (Обратите внимание, что многие поля, установленные на PyBaseObject_Type
и PyType_Type
, действуют по умолчанию).
-
const char *
PyTypeObject
.
tp_name
¶ Указатель на NUL-терминированную строку, содержащую имя типа. Для типов, доступных как глобальные файлы модуля, строка должна представлять собой полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов это должно быть только имя типа. Если модуль является подмодулем пакета, то полное имя пакета является частью полного имени модуля. Например, тип с именем
T
, определенный в модулеM
в подпакетеQ
в пакетеP
, должен иметь инициализаторtp_name
"P.Q.M.T"
.Для dynamically allocated type objects это должно быть просто имя типа, а имя модуля, явно сохраненное в дикте типа в качестве значения для ключа
'__module__'
.Для statically allocated type objects поле tp_name должно содержать точку. Все, что до последней точки, становится доступным как атрибут
__module__
, а все, что после последней точки, становится доступным как атрибут__name__
.Если точка отсутствует, все поле
tp_name
становится доступным как атрибут__name__
, а атрибут__module__
является неопределенным (если он явно не задан в словаре, как объяснялось выше). Это означает, что ваш тип будет невозможно выбрать. Кроме того, он не будет указан в документации модуля, созданной с помощью 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
экземпляра. Существуют исключения: например, ints использует отрицательное полеob_size
для обозначения отрицательного числа, и N тамabs(ob_size)
. Кроме того, наличие поляob_size
в схеме экземпляра не означает, что структура экземпляра имеет переменную длину (например, структура для типа list имеет экземпляры фиксированной длины, но эти экземпляры имеют значимое поле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_VarNew()
, или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
), то после вызова деаллокатора типа деаллокатор должен уменьшить счетчик ссылок для своего объекта типа. Чтобы избежать висячих указателей, рекомендуется следующий способ: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 protocol, более эффективной альтернативы более простому
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()
.Предупреждение
Не рекомендуется, чтобы heap types реализовывал протокол vectorcall. Когда пользователь устанавливает
__call__
в коде Python, обновляется только tp_call, что, вероятно, делает его несовместимым с функцией vectorcall.Изменено в версии 3.8: До версии 3.8 этот слот назывался
tp_print
. В Python 2.x он использовался для печати в файл. В Python 3.0 - 3.7 он не использовался.Наследственность:
Это поле всегда наследуется. Однако флаг
Py_TPFLAGS_HAVE_VECTORCALL
не всегда наследуется. Если это не так, то подкласс не будет использовать vectorcall, за исключением случаев, когда явно вызываетсяPyVectorcall_Call()
. В частности, это относится к heap types (включая подклассы, определенные в Python).
-
getattrfunc
PyTypeObject
.
tp_getattr
¶ Необязательный указатель на функцию get-attribute-string.
Это поле устарело. Когда оно определено, оно должно указывать на функцию, которая действует так же, как функция
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 и asynchronous iterator на уровне 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
¶ Необязательный указатель на функцию get-attribute.
Сигнатура такая же, как и для
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
.По умолчанию:
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()
. Более подробная информация в разделе Поддержка циклической сборки мусора. Этот бит также подразумевает, что связанные с GC поля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.
Наследственность:
Этот флаг никогда не наследуется heap types. Для типов расширения он наследуется всякий раз, когда наследуется
tp_descr_get
.
-
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 protocol. Подробности смотрите в
tp_vectorcall_offset
.Наследственность:
Этот бит наследуется для static subtypes, если также наследуется
tp_call
. Heap types не наследуетсяPy_TPFLAGS_HAVE_VECTORCALL
.Добавлено в версии 3.9.
-
Py_TPFLAGS_IMMUTABLETYPE
¶ Этот бит устанавливается для объектов типа, которые являются неизменяемыми: атрибуты типа не могут быть ни установлены, ни удалены.
PyType_Ready()
автоматически применяет этот флаг к static types.Наследственность:
Этот флаг не наследуется.
Добавлено в версии 3.10.
-
Py_TPFLAGS_DISALLOW_INSTANTIATION
¶ Запретите создание экземпляров типа: установите
tp_new
в NULL и не создавайте ключ__new__
в словаре типов.Флаг должен быть установлен до создания типа, а не после. Например, он должен быть установлен до вызова
PyType_Ready()
для типа.Флаг устанавливается автоматически на static types, если
tp_base
является NULL или&PyBaseObject_Type
иtp_new
является NULL.Наследственность:
Этот флаг не наследуется.
Добавлено в версии 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.
-
-
const char *
PyTypeObject
.
tp_doc
¶ Необязательный указатель на NUL-терминированную 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
необходимо посещать только те члены, которыми экземпляр владеет (имея на них ссылки strong references). Например, если объект поддерживает слабые ссылки через слотtp_weaklist
, указатель, поддерживающий связанный список (на который указывает tp_weaklist), **не должен посещаться, поскольку экземпляр не владеет непосредственно слабыми ссылками на себя (список weakreference существует для поддержки механизма слабых ссылок, но у экземпляра нет сильной ссылки на элементы внутри него, поскольку они могут быть удалены, даже если экземпляр все еще жив).Обратите внимание, что
Py_VISIT()
требует, чтобы параметры visit и arg дляlocal_traverse()
имели эти конкретные имена; не называйте их просто так.Экземпляры heap-allocated types хранят ссылку на свой тип. Поэтому их функция обхода должна либо посетить
Py_TYPE(self)
, либо делегировать эту ответственность, вызвавtp_traverse
другого типа, выделенного из кучи (например, суперкласса, выделенного из кучи). Если этого не сделать, объект типа может быть не собран в мусор.Изменено в версии 3.9: Ожидается, что типы, выделенные из кучи, будут посещать
Py_TYPE(self)
вtp_traverse
. В более ранних версиях Python, из-за bug 40217, это может привести к сбоям в подклассах.Наследственность:
Группа:
Py_TPFLAGS_HAVE_GC
,tp_traverse
,tp_clear
Это поле наследуется подтипами вместе с
tp_clear
и битом флагаPy_TPFLAGS_HAVE_GC
: бит флага,tp_traverse
иtp_clear
наследуются от базового типа, если в подтипе они все равны нулю.
-
inquiry
PyTypeObject
.
tp_clear
¶ Необязательный указатель на функцию очистки для сборщика мусора. Используется только в том случае, если установлен бит флага
Py_TPFLAGS_HAVE_GC
. Подпись:int tp_clear(PyObject *);
Функция-член
tp_clear
используется для разрыва ссылочных циклов в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности все функцииtp_clear
в системе должны разорвать все ссылочные циклы. Это тонкий момент, и если у вас есть сомнения, используйте функциюtp_clear
. Например, тип tuple не реализует функциюtp_clear
, потому что можно доказать, что ни один ссылочный цикл не может состоять полностью из кортежей. Поэтому функцииtp_clear
других типов должны быть достаточными для разрушения любого цикла, содержащего кортеж. Это не сразу очевидно, и редко есть веская причина избегать реализацииtp_clear
.Реализации
tp_clear
должны отбросить ссылки экземпляра на те его члены, которые могут быть объектами Python, и установить указатели на эти члены вNULL
, как в следующем примере:static int local_clear(localobject *self) { Py_CLEAR(self->key); Py_CLEAR(self->args); Py_CLEAR(self->kw); Py_CLEAR(self->dict); return 0; }
Макрос
Py_CLEAR()
следует использовать, потому что очистка ссылок является деликатной: ссылка на содержащийся объект не должна уменьшаться до тех пор, пока указатель на содержащийся объект не будет установлен в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 должны быть упорядочены операторами сравнения языка Си (например, это могут быть инты или плавающие числа). Третий аргумент задает запрашиваемую операцию, как для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
¶ Если экземпляры данного типа являются слабоссылающимися, это поле больше нуля и содержит смещение в структуре экземпляра заголовка списка слабых ссылок (игнорируя заголовок GC, если он присутствует); это смещение используется функциями
PyObject_ClearWeakRefs()
и PyWeakref_*. Структура экземпляра должна включать поле типа PyObject*, которое инициализируется вNULL
.Не путайте это поле с
tp_weaklist
; это глава списка для слабых ссылок на сам объект типа.Наследственность:
Это поле наследуется подтипами, но см. правила, перечисленные ниже. Подтип может переопределить это смещение; это означает, что подтип использует другую головку списка слабых ссылок, чем базовый тип. Поскольку глава списка всегда находится через
tp_weaklistoffset
, это не должно быть проблемой.Когда тип, определенный оператором class, не имеет объявления
__slots__
, и ни один из его базовых типов не является слабоссылаемым, тип делается слабоссылаемым путем добавления в схему экземпляра головного слота списка слабых ссылок и установкиtp_weaklistoffset
смещения этого слота.Когда объявление типа
__slots__
содержит слот с именем__weakref__
, этот слот становится главой списка слабых ссылок для экземпляров типа, а смещение слота хранится вtp_weaklistoffset
типа.Если объявление типа
__slots__
не содержит слота с именем__weakref__
, тип наследует свойtp_weaklistoffset
от своего базового типа.
-
getiterfunc
PyTypeObject
.
tp_iter
¶ Необязательный указатель на функцию, которая возвращает iterator для объекта. Его наличие обычно сигнализирует о том, что экземпляры данного типа являются iterable (хотя последовательности могут быть итерируемыми и без этой функции).
Эта функция имеет ту же сигнатуру, что и
PyObject_GetIter()
:PyObject *tp_iter(PyObject *self);
Наследственность:
Это поле наследуется подтипами.
-
iternextfunc
PyTypeObject
.
tp_iternext
¶ Необязательный указатель на функцию, которая возвращает следующий элемент в iterator. Подпись:
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
должен быть установлен в функции init модуля расширения.Наследственность:
Это поле не наследуется подтипами (очевидно).
По умолчанию:
По умолчанию это поле имеет значение
&PyBaseObject_Type
(которое программистам Python известно как типobject
).
-
PyObject *
PyTypeObject
.
tp_dict
¶ Словарь типа хранится здесь по адресу
PyType_Ready()
.Это поле обычно должно быть инициализировано в
NULL
перед вызовом PyType_Ready; оно также может быть инициализировано в словарь, содержащий начальные атрибуты для типа. После того, какPyType_Ready()
инициализировал тип, дополнительные атрибуты типа могут быть добавлены в этот словарь, только если они не соответствуют перегруженным операциям (например,__add__()
).Наследственность:
Это поле не наследуется подтипами (хотя атрибуты, определенные здесь, наследуются через другой механизм).
По умолчанию:
Если это поле
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
¶ Если экземпляры данного типа имеют словарь, содержащий переменные экземпляра, это поле ненулевое и содержит смещение в экземплярах типа словаря переменных экземпляра; это смещение используется
PyObject_GenericGetAttr()
.Не путайте это поле с
tp_dict
; это словарь для атрибутов самого объекта типа.Если значение этого поля больше нуля, оно определяет смещение от начала структуры экземпляра. Если значение меньше нуля, оно определяет смещение от конца структуры экземпляра. Отрицательное смещение требует больших затрат и должно использоваться только в том случае, если структура экземпляра содержит часть переменной длины. Это используется, например, для добавления словаря переменных экземпляра к подтипам
str
илиtuple
. Обратите внимание, что полеtp_basicsize
должно учитывать словарь, добавленный в конец в этом случае, даже если словарь не включен в основную структуру объекта. В системе с размером указателя 4 байта,tp_dictoffset
должно быть установлено в-4
, чтобы указать, что словарь находится в самом конце структуры.Смещение реального словаря в экземпляре может быть вычислено из отрицательного
tp_dictoffset
следующим образом:dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset if dictoffset is not aligned on sizeof(void*): round up to sizeof(void*)
где
tp_basicsize
,tp_itemsize
иtp_dictoffset
берутся из объекта типа, аob_size
- из экземпляра. Абсолютное значение берется потому, что ints использует знакob_size
для хранения знака числа. (Никогда не нужно выполнять это вычисление самостоятельно; за вас это делает_PyObject_GetDictPtr()
).Наследственность:
Это поле наследуется подтипами, но см. правила, перечисленные ниже. Подтип может переопределить это смещение; это означает, что экземпляры подтипа хранят словарь по другому смещению, чем базовый тип. Поскольку словарь всегда находится через
tp_dictoffset
, это не должно быть проблемой.Когда тип, определенный оператором class, не имеет объявления
__slots__
, и ни один из его базовых типов не имеет словаря переменных экземпляра, в схему экземпляра добавляется слот словаря, а параметрtp_dictoffset
устанавливается на смещение этого слота.Когда тип, определенный оператором class, имеет объявление
__slots__
, тип наследует своиtp_dictoffset
от своего базового типа.(Добавление слота с именем
__dict__
к объявлению__slots__
не дает ожидаемого эффекта, а только вызывает путаницу. Возможно, это следует добавить в качестве функции, как и__weakref__
).По умолчанию:
Этот слот не имеет значения по умолчанию. Для static types, если поле
NULL
, то для экземпляров не создается__dict__
.
-
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
и устанавливает исключение при ошибке.Наследственность:
Это поле наследуется подтипами.
По умолчанию:
Для static types это поле не имеет значения по умолчанию.
-
allocfunc
PyTypeObject
.
tp_alloc
¶ Необязательный указатель на функцию распределения экземпляров.
Сигнатура функции следующая:
PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems);
Наследственность:
Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными с помощью оператора class).
По умолчанию:
Для динамических подтипов это поле всегда установлено в
PyType_GenericAlloc()
, чтобы принудительно использовать стандартную стратегию распределения кучи.Для статических подтипов
PyBaseObject_Type
используетPyType_GenericAlloc()
. Это рекомендуемое значение для всех статически определенных типов.
-
newfunc
PyTypeObject
.
tp_new
¶ Необязательный указатель на функцию создания экземпляра.
Сигнатура функции следующая:
PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
Аргумент subtype - это тип создаваемого объекта; аргументы args и kwds представляют позиционные и ключевые аргументы вызова типа. Обратите внимание, что subtype не обязательно должен быть равен типу, чья функция
tp_new
вызывается; это может быть подтип этого типа (но не несвязанный тип).Функция
tp_new
должна вызватьsubtype->tp_alloc(subtype, nitems)
для выделения места для объекта, а затем выполнить только столько дальнейшей инициализации, сколько абсолютно необходимо. Инициализация, которую можно безопасно проигнорировать или повторить, должна быть помещена в обработчикtp_init
. Хорошим эмпирическим правилом является то, что для неизменяемых типов вся инициализация должна происходить вtp_new
, а для изменяемых типов большая часть инициализации должна быть отложена доtp_init
.Установите флаг
Py_TPFLAGS_DISALLOW_INSTANTIATION
, чтобы запретить создание экземпляров типа в Python.Наследственность:
Это поле наследуется подтипами, за исключением того, что оно не наследуется static types, чей
tp_base
являетсяNULL
или&PyBaseObject_Type
.По умолчанию:
Для static types это поле не имеет значения по умолчанию. Это означает, что если слот определен как
NULL
, то тип не может быть вызван для создания новых экземпляров; предположительно существует другой способ создания экземпляров, например, фабричная функция.
-
freefunc
PyTypeObject
.
tp_free
¶ Необязательный указатель на функцию деаллокации экземпляра. Его сигнатура:
void tp_free(void *self);
Инициализатором, совместимым с этой сигнатурой, является
PyObject_Free()
.Наследственность:
Это поле наследуется статическими подтипами, но не динамическими подтипами (подтипами, созданными с помощью оператора class).
По умолчанию:
В динамических подтипах это поле устанавливается в деаллокатор, подходящий для соответствия
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
, определяет эту функцию для различения статически и dynamically allocated types).Наследственность:
Это поле наследуется подтипами.
По умолчанию:
Этот слот не имеет значения по умолчанию. Если это поле равно
NULL
, то в качестве функционального эквивалента используетсяPy_TPFLAGS_HAVE_GC
.
-
PyObject *
PyTypeObject
.
tp_bases
¶ Множество базовых типов.
Этот параметр устанавливается для типов, созданных с помощью оператора class. Для статически определенных типов оно должно быть
NULL
.Наследственность:
Это поле не наследуется.
-
PyObject *
PyTypeObject
.
tp_mro
¶ Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая
object
, в порядке разрешения методов.Наследственность:
Это поле не наследуется; оно вычисляется свежим
PyType_Ready()
.
-
PyObject *
PyTypeObject
.
tp_cache
¶ Не используется. Только для внутреннего использования.
Наследственность:
Это поле не наследуется.
-
PyObject *
PyTypeObject
.
tp_subclasses
¶ Список слабых ссылок на подклассы. Только для внутреннего использования.
Наследственность:
Это поле не наследуется.
-
PyObject *
PyTypeObject
.
tp_weaklist
¶ Глава списка слабых ссылок, для слабых ссылок на данный объект типа. Не наследуется. Только для внутреннего использования.
Наследственность:
Это поле не наследуется.
-
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); }
Чтобы это поле учитывалось (даже при наследовании), необходимо также установить бит флага
Py_TPFLAGS_HAVE_FINALIZE
.Также обратите внимание, что в Python, собирающем мусор,
tp_dealloc
может быть вызван из любого потока Python, а не только из потока, создавшего объект (если объект становится частью цикла refcount, этот цикл может быть собран сборщиком мусора в любом потоке). Это не является проблемой для вызовов API Python, поскольку поток, из которого вызывается tp_dealloc, будет владеть глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект в свою очередь уничтожает объекты из какой-либо другой библиотеки C или C++, следует позаботиться о том, чтобы уничтожение этих объектов в потоке, вызвавшем tp_dealloc, не нарушило никаких предположений библиотеки.Наследственность:
Это поле наследуется подтипами.
Добавлено в версии 3.4.
См.также
«Безопасная финализация объекта» (PEP 442)
-
vectorcallfunc
PyTypeObject
.
tp_vectorcall
¶ Функция Vectorcall, используемая для вызовов объекта данного типа. Другими словами, она используется для реализации vectorcall для
type.__call__
. Еслиtp_vectorcall
являетсяNULL
, то используется реализация вызова по умолчанию, использующая__new__
и__init__
.Наследственность:
Это поле никогда не наследуется.
Добавлено в версии 3.9: (поле существует с версии 3.8, но используется только с версии 3.9)
Статические типы¶
Традиционно типы, определенные в коде C, являются статическими, то есть статическая структура PyTypeObject
определяется непосредственно в коде и инициализируется с помощью PyType_Ready()
.
В результате получаются типы, которые ограничены относительно типов, определенных в Python:
Статические типы ограничены одной базой, т.е. они не могут использовать множественное наследование.
Объекты статических типов (но не обязательно их экземпляры) неизменяемы. Невозможно добавить или изменить атрибуты объекта типа из Python.
Объекты статических типов являются общими для всех sub-interpreters, поэтому они не должны содержать специфическое для суб-интерпретатора состояние.
Также, поскольку PyTypeObject
не является частью stable ABI, любые модули расширения, использующие статические типы, должны быть скомпилированы для конкретной минорной версии Python.
Типы куч¶
Альтернативой static types являются выделенные из кучи типы, или сокращенно типы кучи, которые близко соответствуют классам, созданным с помощью оператора class
в Python. У типов кучи установлен флаг Py_TPFLAGS_HEAPTYPE
.
Это делается путем заполнения структуры PyType_Spec
и вызова PyType_FromSpec()
, PyType_FromSpecWithBases()
или PyType_FromModuleAndSpec()
.
Структуры числовых объектов¶
-
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()
,PyObject_SetSlice()
иPyObject_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
¶ Эта структура содержит указатели на функции, требуемые Buffer protocol. Протокол определяет, как объект-экспортер может предоставлять свои внутренние данные объектам-потребителям.
-
getbufferproc
PyBufferProcs
.
bf_getbuffer
¶ Сигнатура этой функции следующая:
int (PyObject *exporter, Py_buffer *view, int flags);
Обработка запроса к exporter на заполнение view, как указано flags. За исключением пункта (3), реализация этой функции ДОЛЖНА выполнить следующие действия:
Проверьте, может ли быть выполнен запрос. Если нет, поднять
PyExc_BufferError
, установить view->obj вNULL
и вернуть-1
.Заполните требуемые поля.
Увеличивает внутренний счетчик количества экспортированных товаров.
Установите view->obj на exporter и увеличьте view->obj.
Возврат
0
.
Если exporter является частью цепочки или дерева провайдеров буферов, можно использовать две основные схемы:
Реэкспорт: Каждый член дерева действует как экспортирующий объект и устанавливает view->obj в новую ссылку на себя.
Перенаправление: Запрос буфера перенаправляется на корневой объект дерева. Здесь view->obj будет новой ссылкой на корневой объект.
Отдельные поля view описаны в разделе Buffer structure, правила, как экспортер должен реагировать на конкретные запросы - в разделе Buffer request types.
Вся память, на которую указывает структура
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 и asynchronous iterator.
Вот определение структуры:
typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; sendfunc am_send; } PyAsyncMethods;
-
unaryfunc
PyAsyncMethods
.
am_await
¶ Сигнатура этой функции следующая:
PyObject *am_await(PyObject *self);
Возвращаемый объект должен быть iterator, т.е.
PyIter_Check()
должен вернуть для него1
.Этот слот может быть установлен в
NULL
, если объект не является awaitable.
-
unaryfunc
PyAsyncMethods
.
am_aiter
¶ Сигнатура этой функции следующая:
PyObject *am_aiter(PyObject *self);
Должен возвращать объект asynchronous iterator. Подробности см. в разделе
__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)¶ - Part of the Stable ABI.
Цель этой функции - отделить выделение памяти от ее инициализации. Она должна возвращать указатель на блок памяти достаточной длины для данного экземпляра, соответствующим образом выровненный и инициализированный нулями, но с
ob_refcnt
, установленным на1
иob_type
, установленным на аргумент типа. Еслиtp_itemsize
типа ненулевой, полеob_size
объекта должно быть инициализировано в nitems, а длина выделенного блока памяти должна бытьtp_basicsize + nitems*tp_itemsize
, округленная до кратногоsizeof(void*)
; в противном случае nitems не используется, а длина блока должна бытьtp_basicsize
.Эта функция не должна делать никакой другой инициализации экземпляра, даже выделять дополнительную память; это должно быть сделано
tp_new
.
-
typedef void (*
destructor
)(PyObject*)¶ - Part of the Stable ABI.
-
typedef PyObject *(*
reprfunc
)(PyObject*)¶ - Part of the Stable ABI.
См.
tp_repr
.
-
typedef PyObject *(*
getattrfunc
)(PyObject *self, char *attr)¶ - Part of the Stable ABI.
Возвращает значение именованного атрибута для объекта.
-
typedef int (*
setattrfunc
)(PyObject *self, char *attr, PyObject *value)¶ - Part of the Stable ABI.
Установить значение именованного атрибута для объекта. Для удаления атрибута аргумент value устанавливается в
NULL
.
-
typedef PyObject *(*
getattrofunc
)(PyObject *self, PyObject *attr)¶ - Part of the Stable ABI.
Возвращает значение именованного атрибута для объекта.
См.
tp_getattro
.
-
typedef int (*
setattrofunc
)(PyObject *self, PyObject *attr, PyObject *value)¶ - Part of the Stable ABI.
Установить значение именованного атрибута для объекта. Для удаления атрибута аргумент value устанавливается в
NULL
.См.
tp_setattro
.
-
typedef PyObject *(*
descrgetfunc
)(PyObject*, PyObject*, PyObject*)¶ - Part of the Stable ABI.
См.
tp_descr_get
.
-
typedef int (*
descrsetfunc
)(PyObject*, PyObject*, PyObject*)¶ - Part of the Stable ABI.
См.
tp_descr_set
.
-
typedef Py_hash_t (*
hashfunc
)(PyObject*)¶ - Part of the Stable ABI.
См.
tp_hash
.
-
typedef PyObject *(*
richcmpfunc
)(PyObject*, PyObject*, int)¶ - Part of the Stable ABI.
См.
tp_richcompare
.
-
typedef PyObject *(*
getiterfunc
)(PyObject*)¶ - Part of the Stable ABI.
См.
tp_iter
.
-
typedef PyObject *(*
iternextfunc
)(PyObject*)¶ - Part of the Stable ABI.
См.
tp_iternext
.
-
typedef Py_ssize_t (*
lenfunc
)(PyObject*)¶ - Part of the Stable ABI.
-
typedef PyObject *(*
unaryfunc
)(PyObject*)¶ - Part of the Stable ABI.
-
typedef PyObject *(*
binaryfunc
)(PyObject*, PyObject*)¶ - Part of the Stable ABI.
-
typedef PyObject *(*
ssizeargfunc
)(PyObject*, Py_ssize_t)¶ - Part of the Stable ABI.
-
typedef int (*
ssizeobjargproc
)(PyObject*, Py_ssize_t)¶ - Part of the Stable ABI.
-
typedef int (*
objobjproc
)(PyObject*, PyObject*)¶ - Part of the Stable ABI.
-
typedef int (*
objobjargproc
)(PyObject*, PyObject*, PyObject*)¶ - Part of the Stable ABI.
Примеры¶
Ниже приведены простые примеры определений типов Python. Они включают обычное использование, с которым вы можете столкнуться. Некоторые демонстрируют сложные угловые случаи. Дополнительные примеры, практическая информация и учебник приведены в разделах Определение типов расширений: Учебник и Определение типов расширений: Различные темы.
Базовый static type:
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, instance dicts и hashing:
typedef struct {
PyObject_HEAD
const char *data;
PyObject *inst_dict;
PyObject *weakreflist;
} 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_weaklistoffset = offsetof(MyObject, weakreflist),
.tp_dictoffset = offsetof(MyObject, inst_dict),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
.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, который не может быть подклассифицирован и не может быть вызван для создания экземпляров (например, использует отдельную функцию factory func) с помощью флага 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,
};
Простейший static type с экземплярами фиксированной длины:
typedef struct {
PyObject_HEAD
} MyObject;
static PyTypeObject MyObject_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "mymod.MyObject",
};
Простейший static type с экземплярами переменной длины:
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 *),
};