Введите объекты¶
Возможно, одной из наиболее важных структур объектной системы Python является структура, которая определяет новый тип: структура PyTypeObject
. С объектами типа можно работать с помощью любой из функций PyObject_*
или PyType_*
, но они не предлагают ничего интересного для большинства приложений на Python. Эти объекты имеют фундаментальное значение для поведения объектов, поэтому они очень важны для самого интерпретатора и для любого модуля расширения, реализующего новые типы.
Объекты Type довольно велики по сравнению с большинством стандартных типов. Причина такого размера в том, что каждый объект type хранит большое количество значений, в основном указателей на функции C, каждое из которых реализует небольшую часть функциональности типа. Поля типа object подробно рассматриваются в этом разделе. Поля будут описаны в том порядке, в котором они встречаются в структуре.
В дополнение к приведенному ниже краткому справочнику, в разделе Примеры дается краткое представление о значении и использовании PyTypeObject
.
Краткий справочник¶
«слоты tp»¶
Слот PyTypeObject |
специальные методы/атрибуты |
Информация [2] |
||||
---|---|---|---|---|---|---|
O |
T |
D |
Я |
|||
<R> |
постоянный символ * |
__name__ |
X |
X |
||
X |
X |
X |
||||
X |
X |
|||||
X |
X |
X |
||||
X |
X |
|||||
__получить атрибут__, __getattr__ |
G |
|||||
__установить значение__, __удалить значение__ |
G |
|||||
% |
||||||
__repr__ |
X |
X |
X |
|||
% |
||||||
% |
||||||
% |
||||||
__hash__ |
X |
G |
||||
__call__ |
X |
X |
||||
__стр__ |
X |
X |
||||
__получить атрибут__, __getattr__ |
X |
X |
G |
|||
__установить значение__, __удалить значение__ |
X |
X |
G |
|||
% |
||||||
неподписанный длинный |
X |
X |
? |
|||
постоянный символ * |
__док__ |
X |
X |
|||
X |
G |
|||||
X |
G |
|||||
__lt__, __le__, __eq__, __ne__, __gt__, __ge__ |
X |
G |
||||
X |
? |
|||||
__итер__ |
X |
|||||
__next__ |
X |
|||||
|
X |
X |
||||
|
X |
|||||
|
X |
X |
||||
__base__ |
X |
|||||
|
__дикт__ |
? |
||||
__get__ |
X |
|||||
__установить__, __удалить__ |
X |
|||||
X |
? |
|||||
__инит__ |
X |
X |
X |
|||
X |
? |
? |
||||
__new__ |
X |
X |
? |
? |
||
X |
X |
? |
? |
|||
X |
X |
|||||
|
__основы__ |
~ |
||||
|
__мро__ |
~ |
||||
[ |
|
|||||
|
__подклассы__ |
|||||
|
||||||
( |
||||||
неподписанный int |
||||||
__дел__ |
X |
|||||
дополнительные слоты¶
Слот |
специальные методы |
|
---|---|---|
__await__ |
||
__aiter__ |
||
__анекст__ |
||
__добавить__ __радд__ |
||
__иадд__ |
||
__sub__ __рсуб__ |
||
__изуб__ |
||
__мул__ __рмул__ |
||
__имуль__ |
||
__мод__ __rmod__ |
||
__имод__ |
||
__divmod__ __rdivmod____ |
||
__бах__ __rpow__ |
||
__пов__ |
||
__нег__ |
||
__пос__ |
||
__abs (в )__ |
||
__бул__ |
||
__инвертировать__ |
||
__lshift__ __rlshift сдвиг__ |
||
__илшифт__ |
||
__ршифт__ __рршифт__ |
||
__irshift__ |
||
__и__ __рэнд__ |
||
__ианд__ |
||
__xor__ __rxor__ |
||
__иксор__ |
||
__или__ __ror__ |
||
__иор__ |
||
__инт__ |
||
пустота * |
||
__float__ |
||
__floordiv__ |
||
__ifloordiv__ |
||
__truediv__ |
||
__итруэдив__ |
||
__индекс__ |
||
__матмул__ __рматмул__ |
||
__иматмуль__ |
||
__лен__ |
||
__getitem ( начало )__ |
||
__установить__, __удалить__ |
||
__лен__ |
||
__add__ |
||
__муль__ |
||
__getitem ( начало )__ |
||
__установить__ __делитем__ |
||
__contains__ |
||
__иадд__ |
||
__имуль__ |
||
определения типов слотов¶
typedef - определение типа |
Типы параметров |
Возвращаемый тип |
---|---|---|
|
||
|
пустота |
|
пустота * |
пустота |
|
инт |
||
|
||
инт |
||
|
|
|
PyObject *постоянный символ *
|
|
|
инт |
||
|
||
инт |
||
|
||
инт |
||
|
Py_hash_t |
|
|
||
|
|
|
|
|
|
|
||
инт |
||
пустота |
||
|
инт |
|
PyObject * |
|
|
|
||
|
||
|
||
инт |
||
инт |
||
инт |
Смотрите Тип слота typedefs ниже для получения более подробной информации.
Определение PyTypeObject¶
Структурное определение для PyTypeObject
можно найти в Include/object.h
. Для удобства использования это определение повторяет приведенное здесь определение.:
typedef struct _typeobject {
PyObject_VAR_HEAD
const char *tp_name; /* For printing, in format "<module>.<name>" */
Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
Py_ssize_t tp_vectorcall_offset;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
or tp_reserved (Python 3) */
reprfunc tp_repr;
/* Method suites for standard classes */
PyNumberMethods *tp_as_number;
PySequenceMethods *tp_as_sequence;
PyMappingMethods *tp_as_mapping;
/* More standard operations (here for binary compatibility) */
hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;
/* Functions to access object as input/output buffer */
PyBufferProcs *tp_as_buffer;
/* Flags to define presence of optional/expanded features */
unsigned long tp_flags;
const char *tp_doc; /* Documentation string */
/* Assigned meaning in release 2.0 */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
/* Assigned meaning in release 2.1 */
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
Py_ssize_t tp_weaklistoffset;
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
// Strong reference on a heap type, borrowed reference on a static type
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
Py_ssize_t tp_dictoffset;
initproc tp_init;
allocfunc tp_alloc;
newfunc tp_new;
freefunc tp_free; /* Low-level free-memory routine */
inquiry tp_is_gc; /* For PyObject_IS_GC */
PyObject *tp_bases;
PyObject *tp_mro; /* method resolution order */
PyObject *tp_cache;
PyObject *tp_subclasses;
PyObject *tp_weaklist;
destructor tp_del;
/* Type attribute cache version tag. Added in version 2.6 */
unsigned int tp_version_tag;
destructor tp_finalize;
vectorcallfunc tp_vectorcall;
} PyTypeObject;
Слоты для PyObject¶
Структура объекта type расширяет структуру PyVarObject
. Поле ob_size
используется для динамических типов (созданных с помощью type_new()
, обычно вызываемых из инструкции class). Обратите внимание, что PyType_Type
(метатип) инициализирует tp_itemsize
, что означает, что его экземпляры (т.е. объекты типа) должны иметь поле ob_size
.
-
Py_ssize_t PyObject.ob_refcnt¶
- Part of the Стабильный ABI.
Это число ссылок на объект типа, инициализируемое значением
1
с помощью макросаPyObject_HEAD_INIT
. Обратите внимание, что для statically allocated type objects экземпляры типа (объекты, у которыхob_type
указывает на тип) не считаются ссылками. Но для dynamically allocated type objects экземпляры действительно считаются ссылками.Наследование:
Это поле не наследуется подтипами.
-
PyTypeObject *PyObject.ob_type¶
- Part of the Стабильный 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 Стабильный ABI.
Для statically allocated type objects это значение должно быть инициализировано равным нулю. Для dynamically allocated type objects это поле имеет особое внутреннее значение.
Наследование:
Это поле не наследуется подтипами.
Слоты PyTypeObject¶
В каждом слоте есть раздел, описывающий наследование. Если PyType_Ready()
может задать значение, когда для поля установлено значение NULL
, то также будет раздел «По умолчанию». (Обратите внимание, что многие поля, заданные в PyBaseObject_Type
и PyType_Type
, фактически используются как значения по умолчанию.)
-
const char *PyTypeObject.tp_name¶
Указатель на строку, заканчивающуюся нулем, содержащую имя типа. Для типов, доступных как глобальные значения модуля, строка должна содержать полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов это должно быть просто имя типа. Если модуль является подмодулем пакета, то полное имя пакета является частью полного имени модуля. Например, тип с именем
T
, определенный в модулеM
в подпакетеQ
в пакетеP
, должен иметьtp_name
инициализатор"P.Q.M.T"
.Для dynamically allocated type objects это должно быть просто имя типа, а имя модуля явно сохранено в type dict как значение для ключа
'__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)
. Ответственность за то, чтобы: c:member:~PyTypeObject.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
. Средство освобождения объекта должно использоваться для выделения экземпляра; обычно это: c:func:PyObject_Del, если экземпляр был выделен с использованием:c:macro: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 protocol, более эффективной альтернативы более простому: c:member:~PyTypeObject.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()
.Предупреждение
Не рекомендуется для mutable heap types реализовывать протокол вызова vector. Когда пользователь устанавливает
__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()
. Это, в частности, относится к типам без установленного флагаPy_TPFLAGS_IMMUTABLETYPE
(включая подклассы, определенные в Python).
-
getattrfunc PyTypeObject.tp_getattr¶
Необязательный указатель на функцию get-attribute-string.
Это поле считается устаревшим. Когда оно определено, оно должно указывать на функцию, которая действует так же, как функция
tp_getattro
, но использует строку C вместо объекта string Python для присвоения имени атрибута.Наследование:
Группа:
tp_getattr
,tp_getattro
Это поле наследуется подтипами вместе с
tp_getattro
: подтип наследует обаtp_getattr
иtp_getattro
от своего базового типа, когда подтипыtp_getattr
иtp_getattro
являются обоимиNULL
.
-
setattrfunc PyTypeObject.tp_setattr¶
Необязательный указатель на функцию для установки и удаления атрибутов.
Это поле считается устаревшим. Когда оно определено, оно должно указывать на функцию, которая действует так же, как функция
tp_setattro
, но использует строку C вместо объекта string 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¶
Указывает на дополнительную структуру, содержащую поля, относящиеся только к объектам, реализующим протокол 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 от родительского типа. Это интерпретируется как эквивалент__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¶
Необязательный указатель на функцию getattribute.
Подпись такая же, как и для
PyObject_GetAttr()
:PyObject *tp_getattro(PyObject *self, PyObject *attr);
Обычно удобно задать для этого поля значение
PyObject_GenericGetAttr()
, что реализует обычный способ поиска атрибутов объекта.Наследование:
Группа:
tp_getattr
,tp_getattro
Это поле наследуется подтипами вместе с
tp_getattr
: подтип наследует обаtp_getattr
иtp_getattro
от своего базового типа, когда подтипыtp_getattr
иtp_getattro
являются обоимиNULL
.По умолчанию:
PyBaseObject_Type
используетPyObject_GenericGetAttr()
.
-
setattrofunc PyTypeObject.tp_setattro¶
Необязательный указатель на функцию для установки и удаления атрибутов.
Подпись такая же, как и для
PyObject_SetAttr()
:int tp_setattro(PyObject *self, PyObject *attr, PyObject *value);
Кроме того, для удаления атрибута необходимо поддерживать значение value равным
NULL
. Обычно для этого поля удобно задать значениеPyObject_GenericSetAttr()
, что реализует обычный способ установки атрибутов объекта.Наследование:
Группа:
tp_setattr
,tp_setattro
Это поле наследуется подтипами вместе с
tp_setattr
: подтип наследует обаtp_setattr
иtp_setattro
от своего базового типа, когда подтипыtp_setattr
иtp_setattro
являются обоимиNULL
.По умолчанию:
PyBaseObject_Type
используетPyObject_GenericSetAttr()
.
-
PyBufferProcs *PyTypeObject.tp_as_buffer¶
Указывает на дополнительную структуру, содержащую поля, относящиеся только к объектам, реализующим интерфейс buffer. Эти поля описаны в Структуры буферных объектов.
Наследование:
Поле
tp_as_buffer
не наследуется, но содержащиеся в нем поля наследуются по отдельности.
-
unsigned long PyTypeObject.tp_flags¶
Это поле представляет собой битовую маску из различных флагов. Некоторые флаги указывают на вариантную семантику для определенных ситуаций; другие используются для указания того, что определенные поля в type object (или в структурах расширения, на которые ссылаются через
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
его экземпляров считается ссылкой на тип, а объект type увеличивается при создании нового экземпляра и уменьшается при уничтожении экземпляра (это не относится к экземплярам подтипов; только к объекту type). тип, на который ссылается ob_type экземпляра, увеличивается или УМЕНЬШАЕТСЯ).Наследование:
???
-
Py_TPFLAGS_BASETYPE¶
Этот бит устанавливается, когда тип может использоваться в качестве базового типа другого типа. Если этот бит не задан, тип не может быть подтипом (аналогично «конечному» классу в Java).
Наследование:
???
-
Py_TPFLAGS_READY¶
Этот бит устанавливается, когда объект типа был полностью инициализирован с помощью
PyType_Ready()
.Наследование:
???
-
Py_TPFLAGS_READYING¶
Этот бит устанавливается, когда
PyType_Ready()
находится в процессе инициализации объекта типа.Наследование:
???
-
Py_TPFLAGS_HAVE_GC¶
Этот бит устанавливается, когда объект поддерживает сборку мусора. Если этот бит установлен, экземпляры должны создаваться с использованием
PyObject_GC_New
и уничтожаться с использованиемPyObject_GC_Del()
. Более подробная информация в разделе Поддержка циклической сборки мусора. Этот бит также подразумевает, что поля, связанные с GCtp_traverse
иtp_clear
, присутствуют в объекте type.Наследование:
Группа:
Py_TPFLAGS_HAVE_GC
,tp_traverse
,tp_clear
Бит флага
Py_TPFLAGS_HAVE_GC
наследуется вместе с полямиtp_traverse
иtp_clear
, т.е. если бит флагаPy_TPFLAGS_HAVE_GC
не указан в подтипе, а бит флага :поля c:member:~PyTypeObject.tp_traverse иtp_clear
в подтипе существуют и имеютNULL
значений.
-
Py_TPFLAGS_DEFAULT¶
Это битовая маска всех битов, которые относятся к существованию определенных полей в type object и его структурах расширения. В настоящее время она включает следующие биты:
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_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
.Наследование:
Этот бит наследуется для типов с установленным флагом
Py_TPFLAGS_IMMUTABLETYPE
, если также наследуетсяtp_call
.Добавлено в версии 3.9.
-
Py_TPFLAGS_IMMUTABLETYPE¶
Этот бит устанавливается для объектов типа, которые являются неизменяемыми: атрибуты типа нельзя ни установить, ни удалить.
PyType_Ready()
автоматически применяет этот флаг к static types.Наследование:
Этот флаг не наследуется.
Добавлено в версии 3.10.
-
Py_TPFLAGS_DISALLOW_INSTANTIATION¶
Запретите создавать экземпляры типа: установите для
tp_new
значение NULL и не создавайте ключ__new__
в словаре типов.Флаг должен быть установлен до создания типа, а не после. Например, он должен быть установлен до того, как для типа будет вызван c:func:PyType_Ready.
Флаг автоматически устанавливается на static types, если
tp_base
равно NULL или&PyBaseObject_Type
иtp_new
равно NULL.Наследование:
Этот флаг не наследуется. Однако экземпляры подклассов будут создаваться только в том случае, если они содержат ненулевое значение
tp_new
(что возможно только через C API).Примечание
Чтобы запретить прямое создание экземпляра класса, но разрешить создание экземпляра его подклассов (например, для abstract base class), не используйте этот флаг. Вместо этого сделайте:c:member:~PyTypeObject.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_HEAPTYPE¶
-
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()
для каждого из членов instances, которые являются объектами 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), не должен ** посещаться, поскольку экземпляр напрямую не владеет слабыми ссылками на себя (список слабых ссылок существует ли поддержка механизма слабых ссылок, но экземпляр не имеет сильной ссылки на элементы внутри него, поскольку их разрешено удалять, даже если экземпляр все еще жив).Обратите внимание, что
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()
, поскольку очистка ссылок является деликатной задачей: ссылка на содержащийся объект не должна освобождаться (с помощью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 должны быть упорядочены с помощью операторов сравнения на языке Си (например, они могут быть целыми числами на языке Си или числами с плавающей точкой). Третий аргумент указывает запрашиваемую операцию, как дляPyObject_RichCompare()
.Возвращаемое значение является новым strong reference.
При ошибке устанавливает исключение и возвращает
NULL
из функции.Добавлено в версии 3.7.
Наследование:
Группа:
tp_hash
,tp_richcompare
Это поле наследуется подтипами вместе с
tp_hash
: подтип наследуетtp_richcompare
иtp_hash
, когда подтипtp_richcompare
иtp_hash
являются обоимиNULL
.По умолчанию:
PyBaseObject_Type
предоставляет реализациюtp_richcompare
, которая может быть унаследована. Однако, если определено толькоtp_hash
, даже унаследованная функция не используется, и экземпляры этого типа не смогут участвовать ни в каких сравнениях.-
Py_LT¶
-
Py_ssize_t PyTypeObject.tp_weaklistoffset¶
Если экземпляры этого типа имеют слабую возможность ссылаться, это поле больше нуля и содержит смещение в структуре экземпляра заголовка списка слабых ссылок (игнорируя заголовок GC, если он присутствует); это смещение используется: c:func:PyObject_ClearWeakRefs и
PyWeakref_*
функции. Структура экземпляра должна включать поле типа PyObject*, которое инициализируется значениемNULL
.Не путайте это поле с
tp_weaklist
; это заголовок списка для слабых ссылок на сам объект типа.Наследование:
Это поле наследуется подтипами, но смотрите правила, перечисленные ниже. Подтип может переопределять это смещение; это означает, что подтип использует заголовок weakreferencelist, отличный от базового типа. Поскольку заголовок списка всегда находится через : c:member:~PyTypeObject.tp_weaklistoffset, это не должно быть проблемой.
Когда тип, определенный оператором class, не имеет объявления
__slots__
и ни один из его базовых типов не является слабо ссылочным, этот тип становится слабо ссылочным путем добавления в макет экземпляра заголовка списка слабых ссылок и установкиtp_weaklistoffset
из этот слот смещен.Когда объявление типа
__slots__
содержит ячейку с именем__weakref__
, эта ячейка становится заголовком списка слабых ссылок для экземпляров типа, а смещение ячейки сохраняется в типеtp_weaklistoffset
.Когда объявление типа
__slots__
не содержит интервала с именем__weakref__
, тип наследует свойtp_weaklistoffset
от своего базового типа.
-
getiterfunc PyTypeObject.tp_iter¶
Необязательный указатель на функцию, которая возвращает значение iterator для объекта. Его наличие обычно указывает на то, что экземпляры этого типа являются iterable (хотя последовательности могут быть итерируемыми и без этой функции).
Эта функция имеет ту же сигнатуру, что и:c:func: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
.Наследование:
Это поле не наследуется подтипами (очевидно).
По умолчанию:
Это поле по умолчанию имеет значение
&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
; это словарь атрибутов самого типа object.Если значение этого поля больше нуля, оно указывает смещение от начала структуры экземпляра. Если значение меньше нуля, оно указывает смещение от конца структуры экземпляра. Отрицательное смещение обходится дороже, и его следует использовать только в том случае, если структура экземпляра содержит часть переменной длины. Это используется, например, для добавления словаря переменных экземпляра к подтипам
str
илиtuple
. Обратите внимание, что в этом случае полеtp_basicsize
должно учитывать словарь, добавленный в конец, даже если словарь не включен в базовую компоновку объекта. В системе с размером указателя в 4 байта значениеtp_dictoffset
должно быть равно-4
, чтобы указать, что словарь находится в самом конце структуры.Параметр
tp_dictoffset
следует рассматривать как доступный только для записи. Чтобы получить указатель на словарь, вызовитеPyObject_GenericGetDict()
. При вызовеPyObject_GenericGetDict()
может потребоваться выделить память для словаря, поэтому может оказаться более эффективным вызватьPyObject_GetAttr()
при обращении к атрибуту объекта.Наследование:
Это поле наследуется подтипами, но смотрите правила, перечисленные ниже. Подтип может переопределять это смещение; это означает, что экземпляры подтипа хранят словарь со смещением, отличным от базового типа. Поскольку словарь всегда можно найти через
tp_dictoffset
, это не должно быть проблемой.Когда тип, определенный оператором class, не имеет объявления
__slots__
и ни один из его базовых типов не имеет переменной экземпляра dictionary, в макет экземпляра добавляется ячейка словаря, а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¶
Кортеж базовых типов.
Для этого поля должно быть установлено значение
NULL
и оно должно быть доступно только для чтения. Python заполнит его, если тип поля будетinitialized
.Для динамически создаваемых классов вместо аргумента bases в
PyType_FromSpecWithBases()
можно использоватьPy_tp_bases
slot
. Предпочтительна форма аргумента.Предупреждение
Множественное наследование плохо работает для статически определенных типов. Если вы зададите
tp_bases
для кортежа, Python не выдаст ошибку, но некоторые слоты будут наследоваться только от первой базы.Наследование:
Это поле не наследуется.
-
PyObject *PyTypeObject.tp_mro¶
Кортеж, содержащий расширенный набор базовых типов, начиная с самого типа и заканчивая
object
, в порядке разрешения метода.Для этого поля должно быть установлено значение
NULL
и оно должно быть доступно только для чтения. Python заполнит его, если тип поля будетinitialized
.Наследование:
Это поле не наследуется; оно вычисляется заново по формуле
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); }
Также обратите внимание, что в Python, собирающем мусор,
tp_dealloc
может вызываться из любого потока Python, а не только из потока, создавшего объект (если объект становится частью цикла повторного подсчета, этот цикл может быть собран сборщиком мусора в любом потоке).. Это не проблема для вызовов Python API, поскольку поток, в котором вызывается tp_dealloc, будет владеть глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый объект, в свою очередь, уничтожает объекты из какой-либо другой библиотеки C или C++, следует позаботиться о том, чтобы уничтожение этих объектов в потоке, который вызвал tp_dealloc, не нарушало никаких предположений библиотеки.Наследование:
Это поле наследуется подтипами.
Добавлено в версии 3.4.
Изменено в версии 3.8: До версии 3.8 для использования этого поля необходимо было установить бит флагов
Py_TPFLAGS_HAVE_FINALIZE
. Это больше не требуется.См.также
«Завершение строительства безопасного объекта» (PEP 442)
-
vectorcallfunc PyTypeObject.tp_vectorcall¶
Функция векторного вызова, используемая для вызовов объекта этого типа. Другими словами, она используется для реализации vectorcall для
type.__call__
. Еслиtp_vectorcall
равноNULL
, то используется реализация вызова по умолчанию с использованием__new__()
и__init__()
.Наследование:
Это поле никогда не наследуется.
Добавлено в версии 3.9: (поле существует с версии 3.8, но используется только с версии 3.9)
Статические типы¶
Традиционно типы, определенные в коде C, являются статическими, то есть статическая структура PyTypeObject
определяется непосредственно в коде и инициализируется с помощью PyType_Ready()
.
Это приводит к созданию типов, которые ограничены по сравнению с типами, определенными в Python:
Статические типы ограничены одной базой, то есть они не могут использовать множественное наследование.
Объекты статического типа (но не обязательно их экземпляры) являются неизменяемыми. Добавить или изменить атрибуты объекта типа из Python невозможно.
Объекты статического типа являются общими для всех sub-interpreters, поэтому они не должны включать какое-либо состояние, зависящее от субинтерпретатора.
Кроме того, поскольку PyTypeObject
является только частью Limited API в виде непрозрачной структуры, любые модули расширения, использующие статические типы, должны быть скомпилированы для конкретной младшей версии Python.
Типы кучи¶
Альтернативой static types являются типы, выделяемые в куче, или сокращенно heap types, которые полностью соответствуют классам, созданным с помощью инструкции class
в Python. Для типов кучи установлен флаг Py_TPFLAGS_HEAPTYPE
.
Это делается путем заполнения структуры PyType_Spec
и вызова PyType_FromSpec()
, PyType_FromSpecWithBases()
или PyType_FromModuleAndSpec()
.
Числовые структуры объектов¶
-
type PyNumberMethods¶
Эта структура содержит указатели на функции, которые объект использует для реализации протокола number. Каждая функция используется функцией с аналогичным названием, описанной в разделе Протокол нумерации.
Вот определение структуры:
typedef struct { binaryfunc nb_add; binaryfunc nb_subtract; binaryfunc nb_multiply; binaryfunc nb_remainder; binaryfunc nb_divmod; ternaryfunc nb_power; unaryfunc nb_negative; unaryfunc nb_positive; unaryfunc nb_absolute; inquiry nb_bool; unaryfunc nb_invert; binaryfunc nb_lshift; binaryfunc nb_rshift; binaryfunc nb_and; binaryfunc nb_xor; binaryfunc nb_or; unaryfunc nb_int; void *nb_reserved; unaryfunc nb_float; binaryfunc nb_inplace_add; binaryfunc nb_inplace_subtract; binaryfunc nb_inplace_multiply; binaryfunc nb_inplace_remainder; ternaryfunc nb_inplace_power; binaryfunc nb_inplace_lshift; binaryfunc nb_inplace_rshift; binaryfunc nb_inplace_and; binaryfunc nb_inplace_xor; binaryfunc nb_inplace_or; binaryfunc nb_floor_divide; binaryfunc nb_true_divide; binaryfunc nb_inplace_floor_divide; binaryfunc nb_inplace_true_divide; unaryfunc nb_index; binaryfunc nb_matrix_multiply; binaryfunc nb_inplace_matrix_multiply; } PyNumberMethods;
Примечание
Двоичные и троичные функции должны проверять тип всех своих операндов и выполнять необходимые преобразования (по крайней мере, один из операндов является экземпляром определенного типа). Если операция не определена для заданных операндов, двоичные и троичные функции должны возвращать
Py_NotImplemented
, если произошла другая ошибка, они должны возвращатьNULL
и устанавливать исключение.Примечание
Поле
nb_reserved
всегда должно бытьNULL
. Ранее оно называлосьnb_long
и было переименовано в Python 3.0.1.
-
binaryfunc PyNumberMethods.nb_add¶
-
binaryfunc PyNumberMethods.nb_subtract¶
-
binaryfunc PyNumberMethods.nb_multiply¶
-
binaryfunc PyNumberMethods.nb_remainder¶
-
binaryfunc PyNumberMethods.nb_divmod¶
-
ternaryfunc PyNumberMethods.nb_power¶
-
unaryfunc PyNumberMethods.nb_negative¶
-
unaryfunc PyNumberMethods.nb_positive¶
-
unaryfunc PyNumberMethods.nb_absolute¶
-
inquiry PyNumberMethods.nb_bool¶
-
unaryfunc PyNumberMethods.nb_invert¶
-
binaryfunc PyNumberMethods.nb_lshift¶
-
binaryfunc PyNumberMethods.nb_rshift¶
-
binaryfunc PyNumberMethods.nb_and¶
-
binaryfunc PyNumberMethods.nb_xor¶
-
binaryfunc PyNumberMethods.nb_or¶
-
unaryfunc PyNumberMethods.nb_int¶
-
void *PyNumberMethods.nb_reserved¶
-
unaryfunc PyNumberMethods.nb_float¶
-
binaryfunc PyNumberMethods.nb_inplace_add¶
-
binaryfunc PyNumberMethods.nb_inplace_subtract¶
-
binaryfunc PyNumberMethods.nb_inplace_multiply¶
-
binaryfunc PyNumberMethods.nb_inplace_remainder¶
-
ternaryfunc PyNumberMethods.nb_inplace_power¶
-
binaryfunc PyNumberMethods.nb_inplace_lshift¶
-
binaryfunc PyNumberMethods.nb_inplace_rshift¶
-
binaryfunc PyNumberMethods.nb_inplace_and¶
-
binaryfunc PyNumberMethods.nb_inplace_xor¶
-
binaryfunc PyNumberMethods.nb_inplace_or¶
-
binaryfunc PyNumberMethods.nb_floor_divide¶
-
binaryfunc PyNumberMethods.nb_true_divide¶
-
binaryfunc PyNumberMethods.nb_inplace_floor_divide¶
-
binaryfunc PyNumberMethods.nb_inplace_true_divide¶
-
unaryfunc PyNumberMethods.nb_index¶
-
binaryfunc PyNumberMethods.nb_matrix_multiply¶
-
binaryfunc PyNumberMethods.nb_inplace_matrix_multiply¶
Отображение структур объектов¶
-
type PyMappingMethods¶
Эта структура содержит указатели на функции, которые объект использует для реализации протокола сопоставления. Она состоит из трех элементов:
-
lenfunc PyMappingMethods.mp_length¶
Эта функция используется
PyMapping_Size()
иPyObject_Size()
и имеет одинаковую сигнатуру. Для этого интервала может быть установлено значениеNULL
, если объект не имеет определенной длины.
-
binaryfunc PyMappingMethods.mp_subscript¶
Эта функция используется
PyObject_GetItem()
иPySequence_GetSlice()
и имеет ту же сигнатуру, что иPyObject_GetItem()
. Этот интервал должен быть заполнен, чтобы функцияPyMapping_Check()
возвращала1
, в противном случае это может бытьNULL
.
-
objobjargproc PyMappingMethods.mp_ass_subscript¶
Эта функция используется
PyObject_SetItem()
,PyObject_DelItem()
,PySequence_SetSlice()
иPySequence_DelSlice()
. Он имеет ту же сигнатуру, что иPyObject_SetItem()
, но v также может быть установлен в значениеNULL
для удаления элемента. Если этот интервал равенNULL
, объект не поддерживает назначение и удаление элемента.
Структуры объектов последовательности¶
-
type PySequenceMethods¶
Эта структура содержит указатели на функции, которые объект использует для реализации протокола последовательности.
-
lenfunc PySequenceMethods.sq_length¶
Эта функция используется
PySequence_Size()
иPyObject_Size()
и имеет одинаковую сигнатуру. Он также используется для обработки отрицательных индексов через слотыsq_item
иsq_ass_item
.
-
binaryfunc PySequenceMethods.sq_concat¶
Эта функция используется
PySequence_Concat()
и имеет ту же сигнатуру. Она также используется оператором+
после попытки сложения чисел через слотnb_add
.
-
ssizeargfunc PySequenceMethods.sq_repeat¶
Эта функция используется
PySequence_Repeat()
и имеет ту же сигнатуру. Она также используется оператором*
после попытки умножения чисел через слотnb_multiply
.
-
ssizeargfunc PySequenceMethods.sq_item¶
Эта функция используется
PySequence_GetItem()
и имеет ту же сигнатуру. Она также используетсяPyObject_GetItem()
после попытки подписки через слотmp_subscript
. Этот интервал должен быть заполнен, чтобы функцияPySequence_Check()
возвращала1
, в противном случае это может бытьNULL
.Отрицательные индексы обрабатываются следующим образом: если ячейка
sq_length
заполнена, она вызывается, и длина последовательности используется для вычисления положительного индекса, который передается вsq_item
. Еслиsq_length
равноNULL
, индекс передается функции как есть.
-
ssizeobjargproc PySequenceMethods.sq_ass_item¶
Эта функция используется
PySequence_SetItem()
и имеет ту же сигнатуру. Он также используетсяPyObject_SetItem()
иPyObject_DelItem()
после попытки присвоения и удаления элемента через слотmp_ass_subscript
. Этот интервал может быть оставлен наNULL
, если объект не поддерживает назначение и удаление элементов.
-
objobjproc PySequenceMethods.sq_contains¶
Эта функция может использоваться
PySequence_Contains()
и имеет ту же сигнатуру. Этот интервал может быть оставлен равнымNULL
, в этом случаеPySequence_Contains()
просто обходит последовательность, пока не найдет совпадение.
-
binaryfunc PySequenceMethods.sq_inplace_concat¶
Эта функция используется
PySequence_InPlaceConcat()
и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его. Этот интервал может быть оставлен равнымNULL
, в этом случае значениеPySequence_InPlaceConcat()
вернется к значениюPySequence_Concat()
. Он также используется в расширенном присваивании+=
после попытки числового сложения на месте через слотnb_inplace_add
.
-
ssizeargfunc PySequenceMethods.sq_inplace_repeat¶
Эта функция используется
PySequence_InPlaceRepeat()
и имеет ту же сигнатуру. Она должна изменить свой первый операнд и вернуть его. Этот интервал может быть оставлен равнымNULL
, в этом случае значениеPySequence_InPlaceRepeat()
вернется к значениюPySequence_Repeat()
. Он также используется при выполнении расширенного задания*=
после попытки умножения чисел на месте с помощью слотаnb_inplace_multiply
.
Структуры буферных объектов¶
-
type PyBufferProcs¶
Эта структура содержит указатели на функции, требуемые Buffer protocol. Протокол определяет, как объект-экспортер может предоставлять доступ к своим внутренним данным объектам-потребителям.
-
getbufferproc PyBufferProcs.bf_getbuffer¶
Сигнатурой этой функции является:
int (PyObject *exporter, Py_buffer *view, int flags);
Обработать запрос к экспортеру для заполнения вида, как указано в флагах. За исключением пункта (3), для реализации этой функции НЕОБХОДИМО выполнить следующие действия:
Проверьте, может ли быть выполнен запрос. Если нет, увеличьте значение
BufferError
, установите для view->obj значениеNULL
и верните значение-1
.Заполните необходимые поля.
Увеличьте внутренний счетчик для количества экспортов.
Установите для параметра view->obj значение экспортер и увеличьте значение view->obj.
Верните
0
.
Если экспортер является частью цепочки или дерева поставщиков буферов, можно использовать две основные схемы:
Повторный экспорт: Каждый элемент дерева действует как экспортирующий объект и присваивает view->obj новую ссылку на себя.
Перенаправление: Запрос буфера перенаправляется на корневой объект дерева. Здесь view->obj будет новой ссылкой на корневой объект.
Отдельные поля просмотра описаны в разделе 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
, освободите всю память, связанную с просмотром.
Экспортер ДОЛЖЕН использовать поле
internal
для отслеживания ресурсов, относящихся к конкретному буферу. Гарантируется, что это поле останется неизменным, в то время как потребитель МОЖЕТ передать копию исходного буфера в качестве аргумента просмотр.Эта функция НЕ ДОЛЖНА уменьшать значение 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, т.е. c:func: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.
Тип слота typedefs¶
-
typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)¶
- Part of the Стабильный ABI.
Цель этой функции - отделить выделение памяти от инициализации памяти. Он должен возвращать указатель на блок памяти достаточной длины для экземпляра, соответствующим образом выровненный и инициализированный нулями, но с параметром
ob_refcnt
, равным1
, иob_type
, равным аргументу 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 Стабильный ABI.
-
typedef PyObject *(*newfunc)(PyObject*, PyObject*, PyObject*)¶
- Part of the Стабильный ABI.
Смотрите
tp_new
.
-
typedef int (*initproc)(PyObject*, PyObject*, PyObject*)¶
- Part of the Стабильный ABI.
Смотрите
tp_init
.
-
typedef PyObject *(*reprfunc)(PyObject*)¶
- Part of the Стабильный ABI.
Смотрите
tp_repr
.
-
typedef PyObject *(*getattrfunc)(PyObject *self, char *attr)¶
- Part of the Стабильный ABI.
Возвращает значение именованного атрибута для объекта.
-
typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value)¶
- Part of the Стабильный ABI.
Задайте значение именованного атрибута для объекта. Для удаления атрибута в качестве аргумента value задается значение
NULL
.
-
typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr)¶
- Part of the Стабильный ABI.
Возвращает значение именованного атрибута для объекта.
Смотрите
tp_getattro
.
-
typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)¶
- Part of the Стабильный ABI.
Задайте значение именованного атрибута для объекта. Для удаления атрибута в качестве аргумента value задается значение
NULL
.Смотрите
tp_setattro
.
-
typedef PyObject *(*descrgetfunc)(PyObject*, PyObject*, PyObject*)¶
- Part of the Стабильный ABI.
Смотрите
tp_descr_get
.
-
typedef int (*descrsetfunc)(PyObject*, PyObject*, PyObject*)¶
- Part of the Стабильный ABI.
Смотрите
tp_descr_set
.
-
typedef Py_hash_t (*hashfunc)(PyObject*)¶
- Part of the Стабильный ABI.
Смотрите
tp_hash
.
-
typedef PyObject *(*richcmpfunc)(PyObject*, PyObject*, int)¶
- Part of the Стабильный ABI.
Смотрите
tp_richcompare
.
-
typedef PyObject *(*getiterfunc)(PyObject*)¶
- Part of the Стабильный ABI.
Смотрите
tp_iter
.
-
typedef PyObject *(*iternextfunc)(PyObject*)¶
- Part of the Стабильный ABI.
Смотрите
tp_iternext
.
-
typedef Py_ssize_t (*lenfunc)(PyObject*)¶
- Part of the Стабильный ABI.
-
typedef PyObject *(*unaryfunc)(PyObject*)¶
- Part of the Стабильный ABI.
-
typedef PyObject *(*binaryfunc)(PyObject*, PyObject*)¶
- Part of the Стабильный ABI.
-
typedef PyObject *(*ssizeargfunc)(PyObject*, Py_ssize_t)¶
- Part of the Стабильный ABI.
-
typedef int (*ssizeobjargproc)(PyObject*, Py_ssize_t, PyObject*)¶
- Part of the Стабильный ABI.
-
typedef int (*objobjproc)(PyObject*, PyObject*)¶
- Part of the Стабильный ABI.
-
typedef int (*objobjargproc)(PyObject*, PyObject*, PyObject*)¶
- Part of the Стабильный 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 и хэширование:
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, который не может быть подклассифицирован и не может быть вызван для создания экземпляров (например, использует отдельную фабричную функцию) с использованием флага 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 *),
};