Документация Python неофициальный перевод

slots.md

216 строк · 13.9 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.15/c-api/slots.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Слоты определения89Чтобы определить [объекты модулей](https://python-all.ru/3.15/c-api/module.html#moduleobjects) и [классы](https://python-all.ru/3.15/c-api/type.html#creating-heap-types) с помощью C API, можно использовать массив *слотов* – по сути, пары «ключ-значение», описывающие характеристики создаваемого объекта. Это разделяет данные и структуры, используемые во время выполнения, что позволяет CPython – и другим реализациям C API Python – обновлять структуры без нарушения обратной совместимости.1011В этом разделе описаны слоты в общем. Сведения о поведении конкретных объектов и значениях слотов см. в документации функций, которые применяют слоты:1213- [`PyType_FromSlots()`](https://python-all.ru/3.15/c-api/type.html#c.PyType_FromSlots) для типов;14- [`PyModule_FromSlotsAndSpec()`](https://python-all.ru/3.15/c-api/module.html#c.PyModule_FromSlotsAndSpec) и [хук экспорта расширения](https://python-all.ru/3.15/c-api/extension-modules.html#extension-export-hook) для модулей.1516Когда слоты передаются функции, которая их применяет, функция не изменяет массив слотов и любые данные, на которые он указывает (рекурсивно). После завершения функции вызывающий код может изменять или освобождать массив и любые данные, на которые он указывает (рекурсивно), за исключением данных, явно помеченных [`PySlot_STATIC`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot_STATIC).1718Если не указано иное, в одном массиве слотов не должно быть нескольких слотов с одинаковым ID ([`sl_id`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot.sl_id)).1920Добавлено в версии 3.15: Массивы слотов обобщают более ранний способ определения объектов: с использованием [`PyType_Spec`](https://python-all.ru/3.15/c-api/type.html#c.PyType_Spec) с [`PyType_Slot`](https://python-all.ru/3.15/c-api/type.html#c.PyType_Slot) для типов и [`PyModuleDef`](https://python-all.ru/3.15/c-api/module.html#c.PyModuleDef) с [`PyModuleDef_Slot`](https://python-all.ru/3.15/c-api/module.html#c.PyModuleDef_Slot) для модулей. Более ранний API [мягко устарел](https://python-all.ru/3.15/glossary.html#term-soft-deprecated); планов по его удалению нет.2122Записи массива слотов используют следующую структуру:2324#### `type PySlot`2526*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) (включая все члены) начиная с версии 3.15.*2728Запись в массиве слотов. Определяется как:2930```c31typedef struct {32    uint16_t sl_id;33    uint16_t sl_flags;34    uint32_t _reserved;  // должно быть 035    union {36        void *sl_ptr;37        void (*sl_func)(void);38        Py_ssize_t sl_size;39        int64_t sl_int64;40        uint64_t sl_uint64;41    };42} PySlot;43```4445#### `uint16_t sl_id`4647Идентификатор слота, выбираемый из:4849- `Py_slot_*` значения, описанные в [Общих идентификаторах слотов](https://python-all.ru/3.15/c-api/slots.html#pyslot-common-ids) ниже;50- `Py_mod_*` значения для модулей, как описано в [Определении модулей](https://python-all.ru/3.15/c-api/module.html#c-module-slots);51- Значения для типов, как описано в [Идентификаторах слотов типов](https://python-all.ru/3.15/c-api/type.html#pyslot-type-slot-ids).5253`sl_id`, равный нулю ([`Py_slot_end`](https://python-all.ru/3.15/c-api/slots.html#c.Py_slot_end)), отмечает конец массива слотов.5455#### `void *sl_ptr`5657#### `void (*sl_func)(void)`5859#### `Py_ssize_t sl_size`6061#### `int64_t sl_int64`6263#### `uint64_t sl_uint64`6465Данные для слота. Эти поля являются частью анонимного объединения; используемое поле зависит от типа данных, требуемого идентификатором слота: указатель на данные, указатель на функцию, размер, знаковое или беззнаковое целое число соответственно.6667Если для конкретного идентификатора слота не указано иное, указатели (т.е. `sl_ptr` и `sl_func`) не могут быть NULL.6869#### `uint16_t sl_flags`7071Ноль или более следующих флагов, объединённых операцией ИЛИ:7273#### `PySlot_STATIC`7475*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*7677Все данные, на которые указывает слот, статически размещены и константны. Таким образом, интерпретатору не нужно копировать эту информацию.7879Этот флаг подразумевается для указателей на функции.8081Флаг применяется даже к данным, на которые слот указывает «косвенно», за исключением слотов, вложенных через [`Py_slot_subslots`](https://python-all.ru/3.15/c-api/slots.html#c.Py_slot_subslots), которые могут иметь собственные флаги `PySlot_STATIC`. Например, если применить его к слоту [`Py_tp_members`](https://python-all.ru/3.15/c-api/typeobj.html#c.Py_tp_members), который указывает на массив структур [`PyMemberDef`](https://python-all.ru/3.15/c-api/structures.html#c.PyMemberDef), то весь массив, а также строки имени и документации в его элементах должны быть статическими и константными.8283#### `PySlot_INTPTR`8485*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*8687Данные хранятся в `sl_ptr`; CPython приведёт их к соответствующему типу.8889Этот флаг может упростить перенос из старых структур [`PyType_Slot`](https://python-all.ru/3.15/c-api/type.html#c.PyType_Slot) и [`PyModuleDef_Slot`](https://python-all.ru/3.15/c-api/module.html#c.PyModuleDef_Slot).9091#### `PySlot_OPTIONAL`9293*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*9495Если идентификатор слота неизвестен, интерпретатор должен игнорировать слот, а не завершаться с ошибкой.9697Например, если Python 3.16 добавляет новую возможность с новым идентификатором слота,attr соответствующий слот может быть помечен `PySlot_OPTIONAL`, чтобы Python 3.15 игнорировал его.9899Обратите внимание: «опциональность» применяется только к неизвестным идентификаторам слотов. Этот флаг не заставляет Python пропускать недопустимые значения известных слотов.100101Добавлено в версии 3.15.102103## Вспомогательные макросы104105#### `PySlot_DATA(name, value)`106107#### `PySlot_FUNC(name, value)`108109#### `PySlot_SIZE(name, value)`110111#### `PySlot_INT64(name, value)`112113#### `PySlot_UINT64(name, value)`114115#### `PySlot_STATIC_DATA(name, value)`116117*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*118119Вспомогательные макросы для определения структур `PySlot` с [`sl_id`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot.sl_id) и определённым набором элементов объединения.120121`PySlot_STATIC_DATA` устанавливает флаг [`PySlot_STATIC`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot_STATIC); остальные флаги не устанавливают.122123Обратите внимание: эти макросы используют *именованные инициализаторы* – возможность языка C, которую C++ добавил в версии 2020 года. Если ваш код должен быть совместим с C++11 или более старыми версиями, используйте [`PySlot_PTR`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot_PTR).124125Определено как:126127```c128#define PySlot_DATA(NAME, VALUE) \129   {.sl_id=NAME, .sl_ptr=(void*)(VALUE)}130131#define PySlot_FUNC(NAME, VALUE) \132   {.sl_id=NAME, .sl_func=(VALUE)}133134#define PySlot_SIZE(NAME, VALUE) \135   {.sl_id=NAME, .sl_size=(VALUE)}136137#define PySlot_INT64(NAME, VALUE) \138   {.sl_id=NAME, .sl_int64=(VALUE)}139140#define PySlot_UINT64(NAME, VALUE) \141   {.sl_id=NAME, .sl_uint64=(VALUE)}142143#define PySlot_STATIC_DATA(NAME, VALUE) \144   {.sl_id=NAME, .sl_flags=PySlot_STATIC, .sl_ptr=(VALUE)}145```146147Добавлено в версии 3.15.148149#### `PySlot_END`150151*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*152153Вспомогательный макрос для обозначения конца массива `PySlot`.154155Определено как:156157```c158#define PySlot_END {0}159```160161Добавлено в версии 3.15.162163#### `PySlot_PTR(name, value)`164165#### `PySlot_PTR_STATIC(name, value)`166167*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*168169Вспомогательные макросы для использования в коде, совместимом с C++11. Эта версия C++ не позволяет задавать произвольные элементы объединения в литералах; вместо этого эти макросы устанавливают флаг [`PySlot_INTPTR`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot_INTPTR) и приводят значение к `(void*)`.170171Определено как:172173```c174#define PySlot_PTR(NAME, VALUE) \175   {NAME, PySlot_INTPTR, {0}, {(void*)(VALUE)}}176177#define PySlot_PTR_STATIC(NAME, VALUE) \178   {NAME, PySlot_INTPTR|Py_SLOT_STATIC, {0}, {(void*)(VALUE)}}179```180181Добавлено в версии 3.15.182183## Общие идентификаторы слотов184185Следующие идентификаторы слотов можно использовать как в определениях типов, так и в определениях модулей.186187#### `Py_slot_end`188189*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*190191Обозначает конец массива слотов. Определено как ноль.192193Добавлено в версии 3.15.194195#### `Py_slot_subslots`196197*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*198199Вложенный массив слотов.200201Значение ([`sl_ptr`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot.sl_ptr)) должно указывать на массив структур [`PySlot`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot). Слоты в массиве (до нулевого терминатора, не включая его) будут обрабатываться так, как если бы они были вставлены в текущий массив слотов в точке появления `Py_slot_subslots`.202203Глубина вложенности слотов ограничена 5 уровнями. Это ограничение может быть снято в будущем.204205Добавлено в версии 3.15.206207#### `Py_slot_invalid`208209*Часть [Stable ABI](https://python-all.ru/3.15/c-api/stable.html#stable) начиная с версии 3.15.*210211Зарезервировано; всегда будет рассматриваться как неизвестный идентификатор слота. Определяется как `UINT16_MAX` (`0xFFFF`).212213При использовании с флагом [`PySlot_OPTIONAL`](https://python-all.ru/3.15/c-api/slots.html#c.PySlot_OPTIONAL) определяет слот без эффекта. Без флага обработка слота с таким идентификатором завершится ошибкой.214215Добавлено в версии 3.15.216