Объекты типа¶
Возможно, одной из важнейших структур Python объектной системы является
структура, определяющая новый тип: структура PyTypeObject. Объекты типа могут
обрабатываться с помощью любой из PyObject_*() или PyType_*() функций, но не
предлагают много интересного для большинства Python приложений. Эти объекты
имеют основополагающее значение для поведения объектов, поэтому они очень важны
для самого интерпретатора и для любого модуля расширения, реализующего новые типы.
Объекты типа довольно велики по сравнению с большинством стандартных типов. Причина размера в том, что каждый объект типа хранит большое количество значения, в основном указателей функций C, каждый из которых реализует небольшую часть функциональности типа. В этом разделе подробно рассматриваются поля объекта типа. Поля будут описаны в порядке их появления в структуре.
В дополнение к следующему краткому справочнику, Примеры раздел предоставляет
краткое представление о значении и использовании PyTypeObject.
Краткий справочник¶
«слоты tp»¶
Если COUNT_ALLOCS определено, то также существуют следующие (только внутренние)
поля:
| [1] | Имя слота в скобках указывает на то, что оно (фактически) устарело.
Имена в угловых скобках должны рассматриваться как доступные только для чтения.
Имена в квадратных скобках предназначены только для внутреннего использования.
«<R>» (в качестве префикса) означает, что поле является обязательным (должно
быть не NULL). | 
| [2] | Колонки: «O»: установка на  «T»: установка на  «D»: по умолчанию (если для слота установлено значение  X - PyType_Ready устанавливает значение, если оно равно NULL
~ - PyType_Ready всегда устанавливает значение (оно должно быть NULL)
? - PyType_Ready может установить значение в зависимости от других слотов
См. также столбец наследования ("I").
«I»: наследование X - слот типа наследуется через PyType_Ready, если он определен со значением NULL
% - слоты субструктуры наследуются индивидуально
G - наследуется, но только в сочетании с другими слотами; см. описание слота
? - это сложно; см. описание слота
Следует отметить, что некоторые слоты эффективно наследуются через обычную цепочку поиска атрибута.  | 
подслоты¶
typedefs слотов¶
| typedef | Типы параметров | Возвращаемый тип | 
|---|---|---|
allocfunc | 
Py_ssize_t 
 | 
PyObject * | 
destructor | 
void * | void | 
freefunc | 
void * | void | 
traverseproc | 
int | |
newfunc | 
PyObject * | 
|
initproc | 
int | |
reprfunc | 
PyObject * | 
PyObject * | 
getattrfunc | 
PyObject *const char * 
 | 
PyObject * | 
setattrfunc | 
int | |
getattrofunc | 
PyObject * | 
|
setattrofunc | 
int | |
descrgetfunc | 
PyObject * | 
|
descrsetfunc | 
int | |
hashfunc | 
PyObject * | 
Py_hash_t | 
richcmpfunc | 
PyObject * | 
|
getiterfunc | 
PyObject * | 
PyObject * | 
iternextfunc | 
PyObject * | 
PyObject * | 
lenfunc | 
PyObject * | 
Py_ssize_t | 
getbufferproc | 
int | |
releasebufferproc | 
void | |
inquiry | 
void * | int | 
unaryfunc | 
PyObject * | 
PyObject * | 
binaryfunc | 
PyObject * | 
|
ternaryfunc | 
PyObject * | 
|
ssizeargfunc | 
PyObject *Py_ssize_t 
 | 
PyObject * | 
ssizeobjargproc | 
PyObject *Py_ssize_t 
 | 
int | 
objobjproc | 
int | |
objobjargproc | 
int | 
Для получения более подробной информации см. Тип слота 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 */
    /* call function for all accessible objects */
    traverseproc tp_traverse;
    /* delete references to contained objects */
    inquiry tp_clear;
    /* 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;
    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;
} PyTypeObject;
Слоты PyObject¶
Структура объекта типа расширяет структуру PyVarObject. Поле ob_size
используется для динамических типов (создается type_new(), обычно вызывается из
инструкции class). Обратите внимание, что PyType_Type (метатип) инициализирует
tp_itemsize, что означает, что его сущности (т.е. объекты типа) должны
иметь поле ob_size.
- 
PyObject* 
PyObject._ob_next¶ - 
PyObject * 
PyObject._ob_prev¶ Эти поля присутствуют только при определении
Py_TRACE_REFSмакросов. Об их инициализации вNULLзаботится макросPyObject_HEAD_INIT. Для статически аллоцированных объектов эти поля всегда остаютсяNULL. Для динамически аллоцированных объектов эти два поля используются для связывания объекта с двухсвязным списком всех живых объектов в куче. Это может быть используемо для различных целей отладки; в настоящее время единственным способом использования является печать объектов, которые все еще находятся в рабочем состоянии в конце запуска при установке переменной средыPYTHONDUMPREFS.Наследование:
Эти поля не наследуются подтипами.
- 
Py_ssize_t 
PyObject.ob_refcnt¶ Это число ссылок на объект типа, инициализированное
1для макросаPyObject_HEAD_INIT. Обратите внимание, что для статически аллоцированных объектов типа сущности типа (объекты,ob_typeкоторых указывает на тип) не подсчитываются ссылки. Но для динамически аллоцированных объектов типа, производится подсчет ссылок на экземпляры.Наследование:
Это поле не наследуется подтипами.
- 
PyTypeObject* 
PyObject.ob_type¶ Это тип типа, другими словами, его метатип. Он инициализируется аргументом
PyObject_HEAD_INITмакроса, и его значение обычно&PyType_Type. Однако для динамически загружаемых модулей расширения, которые должны использоваться в Windows (по крайней мере), компилятор жалуется, что это недопустимый инициализатор. Поэтому соглашение должно передаватьNULLмакросуPyObject_HEAD_INITи явно инициализировать это поле в начале функции инициализации модуля, прежде чем делать что-либо другое. Обычно это делается так:Foo_Type.ob_type = &PyType_Type;
Это необходимо сделать до создания любой сущности данного типа.
PyType_Ready()проверяет, является лиob_typeNULL, и если да, инициализирует его в полеob_typeбазового класса.PyType_Ready()не изменит это поле, если оно не равно нулю.Наследование:
Это поле наследуется подтипами.
Слоты PyVarObject¶
- 
Py_ssize_t 
PyVarObject.ob_size¶ Для статически аллоцированных объектов типа это значение должно быть равно нулю. Для динамически аллоцированных объектов типа - это поле имеет особое внутреннее значение.
Наследование:
Это поле не наследуется подтипами.
Слоты PyTypeObject¶
Каждый слот имеет раздел, описывающий наследование. Если PyType_Ready() может
установить значение, если в поле установлено значение NULL то также
будет раздел «По умолчанию». (Обратите внимание, что многие поля, установленные
на PyBaseObject_Type и PyType_Type, эффективно действуют как значения по умолчанию.)
- 
const char* 
PyTypeObject.tp_name¶ Указатель на строку с NUL окончанием, содержащей имя типа. Для типов, доступных в качестве глобальных модулей, строка должна быть полным именем модуля, за которым следует точка, за которой следует имя типа; для встроенных типов это должно быть только имя типа. Если модуль является подмодулем пакета, полное имя пакета является частью полного имени модуля. Например, тип с именем
T, определенный в модулеMв подпакетеQв пакетеP, должен иметь"P.Q.M.T"инициализаторtp_name.Для динамически аллоцированных объектов типа это должно быть только имя типа и имя модуля, явно сохраненное в словаре типа в качестве значения для
'__module__'ключа.Для статически аллоцированных типов объектов, поле tp_name должно содержать точку. Все перед последней точкой становится доступным как
__module__атрибут, а все после последней точки становится доступным как__name__атрибут.Если точки нет, все поле
tp_nameстановится доступным как__name__атрибут, и__module__атрибут не определяется (если не задано явно в словаре, как описано выше). Это означает, что ваш тип будет невозможно pickle. Кроме того, он не будет перечисляться в документации модуля, созданной с помощью pydoc.Это поле не должно быть
NULL. Это единственное требуемое поле вPyTypeObject()(кроме потенциальноtp_itemsize).Наследование:
Это поле не наследуется подтипами.
- 
Py_ssize_t 
PyTypeObject.tp_basicsize¶ - 
Py_ssize_t 
PyTypeObject.tp_itemsize¶ Эти поля позволяют вычислить размер в байтах сущности типа.
Есть два вида типов: у типов с фиксированной длиной, у сущности есть нулевое поле
tp_itemsize, типы с переменной длиной сущности, есть отличное от нуля полеtp_itemsize. Для типа с сущностию фиксированной длины все сущности имеют одинаковый размер, указанный вtp_basicsize.Для типа с сущностию переменной длины, сущности должены иметь поле
ob_size, а размер сущности равенtp_basicsizeплюс N разtp_itemsize, где N - «длина» объекта. Обычно значение N хранится в полеob_sizeсущности. Есть исключения: например, int’ы используют отрицательноеob_sizeдля обозначения отрицательного числа, а N тамabs(ob_size). Кроме того, наличие поляob_sizeв макете сущности не означает, что структура сущности имеет переменную длину (например, структура для типа списка имеет фиксированную длину сущности, но эти сущности имеют значимое полеob_size).Основной размер включает поля в сущности, объявленный макросом
PyObject_HEADилиPyObject_VAR_HEAD(какой бы ни используются, чтобы объявить структуру сущности), и это в свою очередь включает_ob_prevи поля_ob_next, если они присутствуют. Это означает, что единственным правильным способом получения инициализатора дляtp_basicsizeявляется использование оператораsizeofна используются структуры для объявления формата сущности. Базовый размер не включает размер заголовка GC.Примечание о выравнивании: если переменные элементы требуют определенного выравнивания, об этом должено позаботиться значение
tp_basicsize. Пример: предположим, что тип реализует массивdouble.tp_itemsize- этоsizeof(double). Ответственность программиста заключается в том, чтоtp_basicsizeкратноsizeof(double)(при условии, что это требование выравнивания дляdouble).Для любого типа с сущности переменной длины это поле не должно быть
NULL.Наследование:
Эти поля наследуются отдельно подтипами. Если базовый тип имеет ненулевое
tp_itemsize, то, как правило, небезопасно устанавливатьtp_itemsizeна другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).
- 
destructor 
PyTypeObject.tp_dealloc¶ Указатель на функцию деструктора сущности. Функция должна быть определена, если тип не гарантирует, что ее сущности никогда не будет освобождена (как в случае одиночных
NoneиEllipsis). Сигнатура функции:void tp_dealloc(PyObject *self);
Функция деструктора вызывается макросами
Py_DECREF()иPy_XDECREF(), когда количество новых ссылок равно нулю. На данный момент сущность все еще существует, но ссылок на нее нет. Функция деструктора должна освободить все ссылки, которыми владеет сущность, освободить все буферы памяти, принадлежащие сущности (используя функцию освобождения, соответствующую функции распределения используются для аллокация буфера), и вызвать функциюtp_freeтипа. Если тип не является подтипируемым (не имеет установленного бита флагаPy_TPFLAGS_BASETYPE), разрешается вызывать деаллокатор объекта напрямую, а не черезtp_free. Деаллокатор объекта должен использоваться для аллокации сущности; обычно этоPyObject_Del(), если сущность была аллоцирована с использованиемPyObject_New()илиPyObject_VarNew(), илиPyObject_GC_Del()если сущность была аллоцирована с использованиемPyObject_GC_New()илиPyObject_GC_NewVar().Наконец, если типом является аллоцированная куча (
Py_TPFLAGS_HEAPTYPE), деаллокатор должен уменьшить число ссылок для своего объекта типа после вызова деаллокатора типа. Во избежание болтающихся указателей рекомендуется:static void foo_dealloc(foo_object *self) { PyTypeObject *tp = Py_TYPE(self); // здесь свободные ссылки и буферы tp->tp_free(self); Py_DECREF(tp); }
Наследование:
Это поле наследуется подтипами.
- 
Py_ssize_t 
PyTypeObject.tp_vectorcall_offset¶ Необязательное смещение до функции на каждую сущность, которая реализует вызов объекта с использованием протокола vectorcall, более эффективной альтернативы более простого
tp_call.Это поле используются только в том случае, если установлен флаг
_Py_TPFLAGS_HAVE_VECTORCALL. Если это так, это должно быть положительное целое число, содержащее смещение в сущности указателяvectorcallfunc. Это та же сигнатура, что и для_PyObject_Vectorcall():PyObject *vectorcallfunc(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
Указатель vectorcallfunc может быть равен нулю, и в этом случае сущность ведет себя так, как если бы
_Py_TPFLAGS_HAVE_VECTORCALLне был установлен: вызов сущности возвращается кtp_call.Любой класс, задающий
_Py_TPFLAGS_HAVE_VECTORCALL, должен также задатьtp_callи убедиться, что его поведение соответствует функции vectorcallfunc. Это можно сделать, установив для tp_call значениеPyVectorcall_Call:- 
PyObject *
PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)¶ Вызов vectorcallfunc callable с позиционными и ключевыми аргументами, приведенными в кортеже и словаре соответственно.
Функция предназначена для использования в слоте
tp_call. Она не возвращается кtp_callи в настоящее время не проверяет флаг_Py_TPFLAGS_HAVE_VECTORCALL. Для вызова объекта используйте одну изPyObject_Callфункций.
Примечание
Не рекомендуется типам кучи реализовывать протокол vectorcall. Когда пользователь устанавливает
__call__в Python коде, обновляется толькоtp_call, что может привести к несоответствию функции vectorcall.Примечание
Семантика слота
tp_vectorcall_offsetносит предварительный характер и, как ожидается, будет завершена в Python 3.9. Если используется векторколл, запланируйте обновление код для Python 3.9.Изменено в версии 3.8: Этот слот был используются для форматирования печати в файле Python 2.x. В Python 3.0 до 3.7 он был зарезервирован и назван
tp_print.Наследование:
Это поле наследуется подтипами вместе с
tp_call: подтип наследуетtp_vectorcall_offsetот своего базового типа приNULLtp_callподтипа.Обратите внимание, что Типы кучи (включая подклассы, определенные в Python) не наследуют флаг
_Py_TPFLAGS_HAVE_VECTORCALL.- 
PyObject *
 
- 
getattrfunc 
PyTypeObject.tp_getattr¶ Необязательный указатель на функцию получения-атрибута-строки.
Это поле устарело. Когда оно определено, оно должно указывать на функцию, которая действует так же, как функция
tp_getattro, но принимает C строку вместо объекта Python строки, чтобы дать имя атрибуту.Наследование:
Группа:
tp_getattr,tp_getattroЭто поле наследуется подтипами вместе с
tp_getattro: подтип наследует обаtp_getattrиtp_getattroот своего базового типа, когдаtp_getattrиtp_getattroподтипа являютсяNULL.
- 
setattrfunc 
PyTypeObject.tp_setattr¶ Необязательный указатель на функцию для установки и удаления атрибутов.
Это поле устарело. Когда оно определено, оно должно указывать на функцию, которая действует так же, как функция
tp_setattro, но принимает C строку вместо объекта строки Python, чтобы дать имя атрибута.Наследование:
Группа:
tp_setattr,tp_setattroЭто поле наследуется подтипами вместе с
tp_setattro: подтип наследует обаtp_setattrиtp_setattroот своего базового типа, когдаtp_setattrиtp_setattroподтипа являютсяNULL.
- 
PyAsyncMethods* 
PyTypeObject.tp_as_async¶ Указатель на дополнительную структуру, содержащую поля, относящиеся только к объектам, реализующим протоколы awaitable и асинхронный итератор на C-уровне. Дополнительные сведения см. в разделе Асинхронные структуры объектов.
Добавлено в версии 3.5: Ранее известна как
tp_compareиtp_reserved.Наследование:
Поле
tp_as_asyncне наследуется, но содержащиеся поля наследуются по отдельности.
- 
reprfunc 
PyTypeObject.tp_repr¶ Необязательный указатель на функцию, реализующую встроенную функцию
repr().Та же сигнатура, что и для
PyObject_Repr():PyObject *tp_repr(PyObject *self);
Функция должна возвращать объект строки или Юникода. В идеале эта функция должна возвращать строку, которая при передаче
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);
Функция должна возвратить объект строки или Юникода. Это должна быть «дружественное» строке представление объекта, так как это представление, которое будет используются, среди прочего, функцией
print().Наследование:
Это поле наследуется подтипами.
По умолчанию:
Если это поле не установлено, вызывается
PyObject_Repr()для возвращения строки представления.
- 
getattrofunc 
PyTypeObject.tp_getattro¶ Необязательный указатель на функцию получения-атрибута.
Та же сигнатура, что и для
PyObject_GetAttr():PyObject *tp_getattro(PyObject *self, PyObject *attr);
Обычно удобно установить для этого поля значение
PyObject_GenericGetAttr(), которое реализует обычный способ поиска атрибутов объектов.Наследование:
Группа:
tp_getattr,tp_getattroЭто поле наследуется подтипами вместе с
tp_getattr: подтип наследует обаtp_getattrиtp_getattroот своего базового типа, когдаtp_getattrиtp_getattroподтипа являютсяNULL.По умолчанию:
PyBaseObject_TypeиспользуетPyObject_GenericGetAttr().
- 
setattrofunc 
PyTypeObject.tp_setattro¶ Необязательный указатель на функцию для установки и удаления атрибутов.
Та же сигнатура, что и для
PyObject_SetAttr():PyObject *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 при создании нового сущности и DECRF при уничтожении сущности (это не относится к сущности подтипов; только тип, на который ссылается ob_type сущности, получает INCREF или DECREF).Наследование:
???
- 
Py_TPFLAGS_BASETYPE¶ Бит устанавливается, когда тип может быть использован как базовый тип другого типа. Если этот бит чист, тип не может быть подтипом (аналогично «конечному» классу в 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_HAVE_VERSION_TAG.Наследование:
???
- 
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.
Наследование:
Флаг никогда не наследуется типами кучи. Для типов расширений он наследуется всякий раз, когда
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. Дополнительные сведения см. в разделе
tp_vectorcall_offset.Наследование:
Бит устанавливается для статических подтипов, если
tp_flagsне переопределен: подтип наследует_Py_TPFLAGS_HAVE_VECTORCALLот своего базового типа, когдаtp_callподтипаNULL, аPy_TPFLAGS_HEAPTYPEподтипа не задана.Типы кучи не наследуют
_Py_TPFLAGS_HAVE_VECTORCALL.Примечание
Этот флаг является временным и, как ожидается, станет публичным в Python 3.9, с другим названием и, возможно, измененной семантикой. Если используется vectorcall, запланируйте обновление кода для Python 3.9.
Добавлено в версии 3.8.
- 
 
- 
const char* 
PyTypeObject.tp_doc¶ Необязательный указатель на строку C с окончанием NUL, предоставляющий докстринг для объекта этого типа. Он отображается в виде
__doc__, атрибута для типа и сущности типа.Наследование:
Это поле не наследуется подтипами.
- 
traverseproc 
PyTypeObject.tp_traverse¶ Необязательный указатель на функцию обхода сборщика мусора. Используются только в том случае, если установлен бит флага
Py_TPFLAGS_HAVE_GC. Это сигнатура:int tp_traverse(PyObject *self, visitproc visit, void *arg);
Более подробную информацию о Python схеме сбора мусора можно найти в разделе Поддержка циклической сборки мусора.
Указатель
tp_traverseиспользуются сборщиком мусора для обнаружения ссылочных циклов. Типичная реализация функцииtp_traverseпросто вызываетPy_VISIT()на каждом из членов сущности, которые являются Python объектами, которыми владеет сущность. Например, это функция,local_traverse()из модуля расширения_thread:static int local_traverse(localobject *self, visitproc visit, void *arg) { Py_VISIT(self->args); Py_VISIT(self->kw); Py_VISIT(self->dict); return 0; }
Обратите внимание, что
Py_VISIT()вызывается только для тех членов, которые могут участвовать в ссылочных циклах. Хотя есть также членself->key, это может только бытьNULLили Python строка и поэтому не может быть частью ссылочного цикла.С другой стороны, даже если вы знаете, что член никогда не может быть частью цикла, в качестве средства отладки вы может посетить его в любом случае просто
get_referents()функция модуляgcбудет включать его.Предупреждение
При реализации
tp_traverseнеобходимо посещать только те члены, которые владеет сущность (имея на них сильные ссылки). Для сущности, если объект поддерживает слабые ссылки через слотtp_weaklist, указатель, поддерживающий связанный список (на что указывает tp_weaklist) не должен быть посещен, так как сущности напрямую не владеет слабыми ссылками на себя (список слабых ссылок предназначен для поддержки слабого эталонного механизма, но сущности не имеет сильной ссылки на элементы внутри него, поскольку они могут быть удалены, даже если сущности все еще живы).Обратите внимание, что
Py_VISIT()требует, чтобы параметры visit и arglocal_traverse()имели эти конкретные имена; не называйте их просто так.Наследование:
Группа:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearЭто поле наследуется подтипами вместе с
tp_clearи битом флагаPy_TPFLAGS_HAVE_GC: бит флага,tp_traverseиtp_clearнаследуются от базового типа, если все они равны нулю в подтипе.
- 
inquiry 
PyTypeObject.tp_clear¶ Необязательный указатель на функцию очистки для сборщика мусора. Это используются только в том случае, если установлен бит флага
Py_TPFLAGS_HAVE_GC. Сигнатура:int tp_clear(PyObject *);
Функция член
tp_clearиспользуются для разрывания ссылочных циклов в циклическом мусоре, обнаруженном сборщиком мусора. В совокупности всеtp_clearфункции в системе должны объединяться, чтобы разорвать все ссылочные циклы. Это тонко, и если есть сомнения обеспечитьtp_clearфункцию. Например, тип кортежа не реализует функциюtp_clear, поскольку можно доказать, что ни один опорный цикл не может быть полностью составлен из кортежей. Поэтому функцииtp_clearдругих типов должны быть достаточными для разрыва любого цикла, содержащего кортеж. Это не сразу очевидно, и редко есть веские причины, чтобы избежать реализацииtp_clear.Реализации
tp_clearдолжны удалить ссылки сущности на те его элементы, которые могут быть Python объектами, и установить его указатели на эти элементы, чтобыNULL, как в следующем примере:static int local_clear(localobject *self) { Py_CLEAR(self->key); Py_CLEAR(self->args); Py_CLEAR(self->kw); Py_CLEAR(self->dict); return 0; }
Должен использоваться макрос
Py_CLEAR(), поскольку очистка ссылок требует деликатности: ссылка на содержащийся объект не должна уменьшаться до тех пор, пока указатель на содержащийся объект не станетNULL. Это связано с тем, что уменьшение количества ссылок может привести к тому, что содержащийся объект станет мусором, вызывая цепочку операций восстановления, которая может включать в себя вызов произвольного Python кода (из-за завершителей или колбэков слабых ссылок, связанных с содержащимся объектом). Если такой код может снова ссылаться на self, важно, чтобы указатель на содержащийся объект былNULLв это время, чтобы self знал, что содержащийся объект больше не может быть использован. МакросPy_CLEAR()выполняет операции в безопасном порядке.Поскольку цель функций
tp_clearсостоит в том, чтобы разорвать ссылочные циклы, нет необходимости очищать содержащиеся объекты, такие как строки Python или Python целые числа, которые не могут участвовать в ссылочных циклах. С другой стороны, может быть удобно очистить все содержащиеся Python объекты и записать функциюtp_deallocтипа для вызоваtp_clear.Более подробную информацию о Python схеме сбора мусора можно найти в разделе Поддержка циклической сборки мусора.
Наследование:
Группа:
Py_TPFLAGS_HAVE_GC,tp_traverse,tp_clearЭто поле наследуется подтипами вместе с
tp_traverseи битом флагаPy_TPFLAGS_HAVE_GC: бит флага,tp_traverseиtp_clearнаследуются от базового типа, если все они равны нулю в подтипе.
- 
richcmpfunc 
PyTypeObject.tp_richcompare¶ Необязательный указатель на богатую функцию сравнения, сигнатура которой -:
PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);
Первый параметр гарантированно является сущностью типа, который определяется
PyTypeObject.Функция должна возвращать результатом сравнения (обычно
Py_TrueилиPy_False). Если сравнение не определено, оно должно возвращатьPy_NotImplemented, если произошла другая ошибка, она должна возвращатьNULLи задать условие исключения.Следующие константы определяются для использования в качестве третьего аргумента для
tp_richcompareи дляPyObject_RichCompare():Константа Сравнение Py_LT<Py_LE<=Py_EQ==Py_NE!=Py_GT>Py_GE>=Следующий макрос определен для облегчения записи богатой функций сравнения:
- 
Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)¶ Возвращает
Py_TrueилиPy_Falseиз функции в зависимости от результата сравнения. VAL_A и VAL_B должны быть вызваны операторами сравнения C (например, это могут быть C ints или floats). Третий аргумент указывает запрошенную операцию, как для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¶ Необязательный указатель на функцию, которая возвращает итератор для объекта. Его наличие обычно сигнализирует о том, что сущности этого типа являются итерабельными (хотя последовательности могут быть итерабельны без этой функции).
Функция имеет ту же сигнатуру, что и
PyObject_GetIter():PyObject *tp_iter(PyObject *self);
Наследование:
Это поле наследуется подтипами.
- 
iternextfunc 
PyTypeObject.tp_iternext¶ Необязательный указатель на функцию, которая возвращает следующий элемент итератора. Сигнатура:
PyObject *tp_iternext(PyObject *self);
Когда итератор исчерпан, он должен возвращать
NULL; может быть установлено или не установленоStopIterationисключение. При возникновении другой ошибки она также должна возвращатьNULL. Его наличие сигнализирует, что сущности этого типа являются итераторами.Типы итератора также должны определять функцию
tp_iter, и эта функция должна возвращать саму сущность итератора (не новую сущность итератора).Функция имеет те же сигнатуру, что и
PyIter_Next().Наследование:
Это поле наследуется подтипами.
- 
struct PyMethodDef* 
PyTypeObject.tp_methods¶ Необязательный указатель на статический
NULL-завершенный массивPyMethodDefструктур, объявляющий регулярные методы этого типа.Для каждого элемента массива в словарь типа добавляется элемент (см.
tp_dictниже), содержащая дескриптор метода.Наследование:
Это поле не наследуется подтипами (методы наследуются через другой механизм).
- 
struct PyMemberDef* 
PyTypeObject.tp_members¶ Необязательный указатель на статический
NULL-завершенный массивPyMemberDefструктур, объявляющий регулярные элементы данных (поля или слоты) сущности этого типа.Для каждой записи в массиве запись добавляется в словарь типа (см.
tp_dictниже), содержащая дескриптор-член.Наследование:
Это поле не наследуется подтипами (члены наследуются через другой механизм).
- 
struct PyGetSetDef* 
PyTypeObject.tp_getset¶ Необязательный указатель на статический
NULL-завершенный массивPyGetSetDefструктур, объявляющий вычисляемые атрибуты сущности этого типа.Для каждой записи в массиве запись добавляется в словарь типа (см.
tp_dictниже), содержащая дескриптор getset.Наследование:
Это поле не наследуется подтипами (вычисляемые атрибуты наследуются через другой механизм).
- 
PyTypeObject* 
PyTypeObject.tp_base¶ Необязательный указатель на базовый тип, свойства которого наследуются. На этом уровне поддерживается только одиночное наследование; множественное наследование требует динамического создания объекта типа путем вызова метатипа.
Примечание
Инициализация слотов подчиняется правилам инициализации глобальных слотов. C99 требует, чтобы инициализаторы были «адресными константами». Обозначения функций, такие как
PyType_GenericNew(), с неявным преобразованием в указатель являются допустимыми константами C99 адреса.Однако унарный оператор „&“, применяемый к нестатической переменной, подобной
PyBaseObject_Type(), не требуется для создания адресной константы. Компиляторы могут поддерживать это (gcc поддерживает), MSVC поддерживает. Оба компилятора строго соответствуют стандарту в этом конкретном поведении.Следовательно,
tp_baseдолжны быть установлены в функции 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¶ Необязательный указатель на функцию «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__.)По умолчанию:
Этот слот не имеет значения по умолчанию. Для статических типов, если поле является
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и устанавливает исключение при ошибке.Наследование:
Это поле наследуется подтипами.
По умолчанию:
Для статических типов это поле не имеет значения по умолчанию.
- 
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);
Аргумент подтипа - это тип создаваемого объекта; аргументы args и kwds представляют позиционные и ключевые аргументы вызова типа. Обратите внимание, что подтип не должен совпадать с типом,
tp_newфункция которого вызывается; это может быть подтип этого типа (но не несвязанный тип).Функция
tp_newдолжна вызыватьsubtype->tp_alloc(subtype, nitems), чтобы аллоцировать пространство для объекта, а затем выполнить только необходимую инициализацию. Инициализация, которую можно безопасно игнорировать или повторить, должна быть помещена вtp_initобработчик. Хорошим правилом является то, что для неизменяемых типов вся инициализация должна происходить вtp_new, в то время как для изменяемых типов большая часть инициализации должна быть отложена доtp_init.Наследование:
Это поле наследуется подтипами, за исключением того, что оно не наследуется статическими типами,
tp_baseкоторых являетсяNULLили&PyBaseObject_Type.По умолчанию:
Для статических типов это поле не имеет значения по умолчанию. Это означает, что если позиция определена как
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для коллектируемой (collectible) сущности, а0для сущности не подлежащей коллектированию (non-collectible). Сигнатура:int tp_is_gc(PyObject *self);
(Единственный пример - сами типы. Метатип,
PyType_Type, определяет эту функцию, чтобы различать статически и динамически аллоцированные типы.)Наследование:
Это поле наследуется подтипами.
По умолчанию:
Этот слот не имеет значения по умолчанию. Если это поле
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; /* Сохранить текущее исключение, если оно есть. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); /* ... */ /* Восстановление сохраненного исключения. */ PyErr_Restore(error_type, error_value, error_traceback); }
Для учета этого поля (даже при наследовании) необходимо также установить бит флагов
Py_TPFLAGS_HAVE_FINALIZE.Наследование:
Это поле наследуется подтипами.
Добавлено в версии 3.4.
См.также
«Безопасное завершение объекта» (PEP 442)
Остальные поля определяются только в том случае, если определен COUNT_ALLOCS
макроса теста функций, и предназначены только для внутреннего использования. Они
задокументированы здесь для полноты. None из этих полей наследуются
подтипами.
- 
Py_ssize_t 
PyTypeObject.tp_allocs¶ Количество аллокаций.
- 
Py_ssize_t 
PyTypeObject.tp_frees¶ Количество освобождений.
- 
Py_ssize_t 
PyTypeObject.tp_maxalloc¶ Максимальное количество одновременно аллоцированных объектов.
- 
PyTypeObject* 
PyTypeObject.tp_prev¶ Указатель на предыдущий объект типа с ненулевым полем
tp_allocs.
- 
PyTypeObject* 
PyTypeObject.tp_next¶ Указатель на объект следующего типа с ненулевым полем
tp_allocs.
Кроме того, обратите внимание, что со сборкой мусора в Python, tp_dealloc
может вызываться от любого Python потока, не только  из потока, который
создал объект (если объект становится частью refcount цикла, тот цикл мог бы
быть собран сборкой мусора в любом потоке). Это не проблема для Python
вызовов API, так как поток, на котором вызывается tp_dealloc, будет
владеть глобальной блокировкой интерпретатора (GIL). Однако, если уничтожаемый
объект в свою очередь уничтожает объекты из какой-либо другой библиотеки C или
C++, следует позаботиться о том, чтобы уничтожение тех объектов в потоке,
которые вызвали tp_dealloc, не нарушают никаких предположений библиотеки.
Типы кучи¶
Традиционно типы, определенные в C коде, являются статическими, то есть
статическая структура PyTypeObject определяется непосредственно в коде и
инициализируется с помощью PyType_Ready().
Это приводит к типам, которые ограничены по отношению к типам, определенным в Python:
- Статические типы ограничены одним основанием, т.е. они не могут использовать множественное наследование.
 - Объекты статического типа (но не обязательно их сущности) являются неизменяемыми. Невозможно добавить или изменить атрибуты объекта типа из Python.
 - Объекты статического типа совместно используются в разных субинтерпретерах, поэтому они не должны включать состояние, специфичные для субинтерпретера.
 
Кроме того, поскольку PyTypeObject не является частью стабильного ABI,
любые модули расширения, использующие статические типы, должны быть скомпилированы для
определенной Python минорной версии.
Альтернативой статическим типам является типы, размещенные в куче, или типы кучи
для краткости, которые тесно соответствуют классам, созданной Python
инструкцией class.
Это делается путем заполнения структуры PyType_Spec и вызова PyType_FromSpecWithBases().
Числовые структуры объектов¶
- 
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¶ 
- 
inquiry 
PyNumberMethods.nb_bool¶ 
- 
binaryfunc 
PyNumberMethods.nb_lshift¶ 
- 
binaryfunc 
PyNumberMethods.nb_rshift¶ 
- 
binaryfunc 
PyNumberMethods.nb_and¶ 
- 
binaryfunc 
PyNumberMethods.nb_xor¶ 
- 
binaryfunc 
PyNumberMethods.nb_or¶ 
- 
void *
PyNumberMethods.nb_reserved¶ 
- 
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¶ 
- 
binaryfunc 
PyNumberMethods.nb_matrix_multiply¶ 
- 
binaryfunc 
PyNumberMethods.nb_inplace_matrix_multiply¶ 
Сопоставление структур объектов¶
- 
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, объект не поддерживает назначение и удаление позиции.
Последовательность структур объектов¶
- 
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слот.
Буферные структуры объектов¶
- 
PyBufferProcs¶ Структура содержит указатели на функции, требующие буферные протоколы. Протокол определяет, как объект-экспортер может предоставлять свои внутренние данные объектам-потребителям.
- 
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 описаны в разделе Структура буфера, правила реагирования экспортера на конкретные запросы - в разделе Типы запросов буфера.
Вся память, указанная в структуре
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.
- 
PyAsyncMethods¶ Структура содержит указатели на функции, необходимые для реализации awaitable и асинхронный итератор объектов.
Вот определение структуры:
typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; } PyAsyncMethods;
- 
unaryfunc 
PyAsyncMethods.am_await¶ Сигнатура этой функции:
PyObject *am_await(PyObject *self);
Возвращаемый объект должен быть итератором, т.е.
PyIter_Check()должен возвращать1для него.Этот слот может иметь значение
NULL, если объект не является awaitable.
- 
unaryfunc 
PyAsyncMethods.am_aiter¶ Сигнатура этой функции:
PyObject *am_aiter(PyObject *self);
Должен возвращаться объектом awaitable. Дополнительные сведения см. в разделе
__anext__().Этот слот может иметь значение
NULL, если объект не реализует протокол асинхронной итерации.
- 
unaryfunc 
PyAsyncMethods.am_anext¶ Сигнатура этой функции:
PyObject *am_anext(PyObject *self);
Должна возвращать awaitable объект. Дополнительные сведения см. в разделе
__anext__(). Для этого слота может быть установлено значениеNULL.
Тип слота typedefs¶
- 
PyObject *
(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)¶ Назначение этой функции состоит в том, чтобы отделить выделение памяти от инициализации памяти. Она должна возвращать указатель на блок памяти достаточной длины для сущности, соответствующим образом выровненный и инициализированный нулями, но с
ob_refcnt, установлен в1, иob_type, установленным в аргумент типа. Если типаtp_itemsizeненулевое, полеob_sizeобъекта должно быть инициализировано до nitems, а длина аллоцированный блока памяти должна бытьtp_basicsize + nitems*tp_itemsize, округлена до кратногоsizeof(void*); в противном случае nitems не используются, и длина блока должна бытьtp_basicsize.Функция не должна выполнять никакой другой сущности инициализации, даже для аллокации дополнительной памяти; это должно быть сделано
tp_new.
- 
PyObject *
(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)¶ Смотрите
tp_vectorcall_offset.Аргументы для
vectorcallfuncте же, что и для_PyObject_Vectorcall().Добавлено в версии 3.8.
- 
PyObject *
(*getattrfunc)(PyObject *self, char *attr)¶ Возвращает значение именованного атрибута для объекта.
- 
int 
(*setattrfunc)(PyObject *self, char *attr, PyObject *value)¶ Задать значение именованного атрибута для объекта. Значение аргумента устанавливается в
NULLдля удаления атрибута.
- 
PyObject *
(*getattrofunc)(PyObject *self, PyObject *attr)¶ Возвращает значение именованного атрибута для объекта.
Смотрите
tp_getattro.
- 
int 
(*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)¶ Задать значение именованного атрибута для объекта. Значение аргумента устанавливается в
NULLдля удаления атрибутg.Смотрите
tp_setattro.
- 
PyObject *
(*richcmpfunc)(PyObject *, PyObject *, int)¶ Смотрите
tp_richcompare.
- 
PyObject *
(*iternextfunc)(PyObject *)¶ Смотрите
tp_iternext.
Примеры¶
Ниже приведены простые примеры определений типов Python. Они включают общее использование, с которым вы может столкнуться. Некоторые демонстрируют хитроумные угловые случаи. Дополнительные примеры, практические сведения и учебное пособие см. в разделах Определение типов расширений: учебник и Определение типов расширений: ассортированные темы.
Базовый статический тип:
typedef struct {
    PyObject_HEAD
    const char *data;
} MyObject;
static PyTypeObject MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
    .tp_basicsize = sizeof(MyObject),
    .tp_doc = "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 */
    "My objects",                   /* tp_doc */
    0,                              /* tp_traverse */
    0,                              /* tp_clear */
    0,                              /* tp_richcompare */
    0,                              /* tp_weaklistoffset */
    0,                              /* tp_iter */
    0,                              /* tp_iternext */
    0,                              /* tp_methods */
    0,                              /* tp_members */
    0,                              /* tp_getset */
    0,                              /* tp_base */
    0,                              /* tp_dict */
    0,                              /* tp_descr_get */
    0,                              /* tp_descr_set */
    0,                              /* tp_dictoffset */
    0,                              /* tp_init */
    0,                              /* tp_alloc */
    myobj_new,                      /* tp_new */
};
Тип, поддерживающий слабые ссылки, сущности словари и хеширование:
typedef struct {
    PyObject_HEAD
    const char *data;
    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 = "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, который не может быть разделен на подклассы и не может быть вызван для создания экземпляров (например, используя отдельную фабричную функцию):
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 = "my custom str",
    .tp_flags = Py_TPFLAGS_DEFAULT,
    .tp_new = NULL,
    .tp_repr = (reprfunc)myobj_repr,
};
Простейший статический тип (с фиксированной длиной сущности):
typedef struct {
    PyObject_HEAD
} MyObject;
static PyTypeObject MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
};
Простейший статический тип (с переменной длиной сущности):
typedef struct {
    PyObject_VAR_HEAD
    const char *data[1];
} MyObject;
static PyTypeObject MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
    .tp_basicsize = sizeof(MyObject) - sizeof(char *),
    .tp_itemsize = sizeof(char *),
};
