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

dis.md

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

1> **Источник:** https://python-all.ru/3.8/library/dis.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`dis`](https://python-all.ru/3.8/library/dis.html#module-dis) – Дизассемблер байт-кода Python89**Исходный код:** [Lib/dis.py](https://python-all.ru/src/3.8/Lib/dis.py)1011---1213Модуль [`dis`](https://python-all.ru/3.8/library/dis.html#module-dis) поддерживает анализ [байт-кода](https://python-all.ru/3.8/glossary.html#term-bytecode) CPython путём eго дизассемблирования. Байт-код CPython, который этот модуль принимает на вход, определён в файле `Include/opcode.h` и используется компилятором и интерпретатором.1415**Особенность реализации CPython:** Байт-код является деталью реализации интерпретатора CPython. Нет никаких гарантий, что байт-код не будет добавлен, удалён или изменён в разных версиях Python. Не следует рассчитывать, что использование этого модуля будет работать в разных виртуальных машинах Python или в разных релизах Python.1617Изменено в версии 3.6: Для каждой инструкции используется 2 байта. Ранее количество байт зависело от инструкции.1819Пример: Дана функция `myfunc()`:2021```python22def myfunc(alist):23    return len(alist)24```2526следующую команду можно использовать для отображения дизассемблирования `myfunc()`:2728```python29>>> dis.dis(myfunc)30  2           0 LOAD_GLOBAL              0 (len)31              2 LOAD_FAST                0 (alist)32              4 CALL_FUNCTION            133              6 RETURN_VALUE34```3536(«2» – это номер строки).3738## Анализ байт-кода3940Новое в версии 3.4.4142API анализа байт-кода позволяет оборачивать фрагменты кода Python в объект [`Bytecode`](https://python-all.ru/3.8/library/dis.html#dis.Bytecode), который предоставляет удобный доступ к деталям скомпилированного кода.4344#### `class dis.Bytecode(x, *, first_line=None, current_offset=None)`4546Анализирует байткод, соответствующий функции, генератору, асинхронному генератору, корутине, методу, строке исходного кода или объекту кода (как возвращается [`compile()`](https://python-all.ru/3.8/library/functions.html#compile)).4748Это удобная обёртка над многими функциями, перечисленными ниже, особенно [`get_instructions()`](https://python-all.ru/3.8/library/dis.html#dis.get_instructions), поскольку итерация по экземпляру [`Bytecode`](https://python-all.ru/3.8/library/dis.html#dis.Bytecode) возвращает операции байткода в виде экземпляров [`Instruction`](https://python-all.ru/3.8/library/dis.html#dis.Instruction).4950Если *first\_line* не равен `None`, он указывает номер строки, который должен быть указан для первой строки исходного кода в дизассемблированном коде. В противном случае информация о строке исходного кода (если есть) берётся непосредственно из дизассемблированного объекта кода.5152Если *current\_offset* не равно `None`, оно указывает смещение инструкции в дизассемблированном коде. Установка этого значения означает, что [`dis()`](https://python-all.ru/3.8/library/dis.html#dis.Bytecode.dis) будет отображать маркер «текущая инструкция» напротив указанной операции.5354#### `classmethod from_traceback(tb)`5556Создаёт экземпляр [`Bytecode`](https://python-all.ru/3.8/library/dis.html#dis.Bytecode) из заданного traceback, устанавливая *current\_offset* на инструкцию, ответственную за исключение.5758#### `codeobj`5960Скомпилированный объект кода.6162#### `first_line`6364Первая строка исходного кода объекта кода (если доступна)6566#### `dis()`6768Возвращает форматированное представление операций байткода (то же, что выводится [`dis.dis()`](https://python-all.ru/3.8/library/dis.html#dis.dis), но возвращается в виде многострочной строки).6970#### `info()`7172Возвращает форматированную многострочную строку с подробной информацией об объекте кода, как [`code_info()`](https://python-all.ru/3.8/library/dis.html#dis.code_info).7374Изменено в версии 3.7: Теперь может обрабатывать объекты корутин и асинхронных генераторов.7576Пример:7778```python79>>> bytecode = dis.Bytecode(myfunc)80>>> for instr in bytecode:81...     print(instr.opname)82...83LOAD_GLOBAL84LOAD_FAST85CALL_FUNCTION86RETURN_VALUE87```8889## Функции анализа9091Модуль [`dis`](https://python-all.ru/3.8/library/dis.html#module-dis) также определяет следующие функции анализа, которые преобразуют входные данные непосредственно в желаемый вывод. Они могут быть полезны, если выполняется только одна операция, и промежуточный объект анализа не нужен:9293#### `dis.code_info(x)`9495Возвращает форматированную многострочную строку с подробной информацией об объекте кода для указанной функции, генератора, асинхронного генератора, корутины, метода, строки исходного кода или объекта кода.9697Обратите внимание, что точное содержимое строк с информацией о коде сильно зависит от реализации и может произвольно меняться в разных реализациях Python или версиях Python.9899Новое в версии 3.2.100101Изменено в версии 3.7: Теперь может обрабатывать объекты корутин и асинхронных генераторов.102103#### `dis.show_code(x, *, file=None)`104105Выводит подробную информацию об объекте кода для указанной функции, метода, строки исходного кода или объекта кода в *file* (или `sys.stdout`, если *file* не указан).106107Это удобная краткая форма для `print(code_info(x), file=file)`, предназначенная для интерактивного исследования в приглашении интерпретатора.108109Новое в версии 3.2.110111Изменено в версии 3.4: Добавлен параметр *file*.112113#### `dis.dis(x=None, *, file=None, depth=None)`114115Дизассемблирует объект *x*. *x* может быть модулем, классом, методом, функцией, генератором, асинхронным генератором, корутиной, объектом кода, строкой исходного кода или последовательностью байт сырого байт-кода. Для модуля дизассемблируются все функции. Для класса – все методы (включая методы класса и статические методы). Для объекта кода или последовательности сырого байт-кода выводится по одной строке на каждую инструкцию байт-кода. Также рекурсивно дизассемблируются вложенные объекты кода (код включений, генераторных выражений и вложенных функций, а также код, используемый для построения вложенных классов). Строки сначала компилируются в объекты кода с помощью встроенной функции [`compile()`](https://python-all.ru/3.8/library/functions.html#compile), а затем дизассемблируются. Если объект не указан, эта функция дизассемблирует последнюю трассировку.116117Результат дисассемблирования выводится в виде текста в указанный аргумент *file*, если он передан, иначе – в `sys.stdout`.118119Максимальная глубина рекурсии ограничивается параметром *depth*, если только он не равен `None`. `depth=0` означает отсутствие рекурсии.120121Изменено в версии 3.4: Добавлен параметр *file*.122123Изменено в версии 3.7: Реализовано рекурсивное дисассемблирование и добавлен параметр *depth*.124125Изменено в версии 3.7: Теперь может обрабатывать объекты корутин и асинхронных генераторов.126127#### `dis.distb(tb=None, *, file=None)`128129Дисассемблирует функцию, находящуюся на вершине стека traceback; если traceback не передан, используется последний. Указывается инструкция, вызвавшая исключение.130131Результат дисассемблирования выводится в виде текста в указанный аргумент *file*, если он передан, иначе – в `sys.stdout`.132133Изменено в версии 3.4: Добавлен параметр *file*.134135#### `dis.disassemble(code, lasti=-1, *, file=None)`136137#### `dis.disco(code, lasti=-1, *, file=None)`138139Дисассемблирует объект кода, указывая последнюю инструкцию, если передан *lasti*. Результат разбит на следующие столбцы:1401411. номер строки для первой инструкции каждой строки1422. текущая инструкция, помечена как `-->`,1433. инструкция с меткой, помечена `>>`,1444. адрес инструкции,1455. название кода операции,1466. параметры операции и1477. интерпретация параметров в скобках.148149Интерпретация параметров распознаёт имена локальных и глобальных переменных, константные значения, цели переходов и операторы сравнения.150151Результат дисассемблирования выводится в виде текста в указанный аргумент *file*, если он передан, иначе – в `sys.stdout`.152153Изменено в версии 3.4: Добавлен параметр *file*.154155#### `dis.get_instructions(x, *, first_line=None)`156157Возвращает итератор по инструкциям в переданной функции, методе, строке исходного кода или объекте кода.158159Итератор генерирует последовательность именованных кортежей [`Instruction`](https://python-all.ru/3.8/library/dis.html#dis.Instruction), содержащих сведения о каждой операции в переданном коде.160161Если *first\_line* не равен `None`, он указывает номер строки, который должен быть указан для первой строки исходного кода в дизассемблированном коде. В противном случае информация о строке исходного кода (если есть) берётся непосредственно из дизассемблированного объекта кода.162163Новое в версии 3.4.164165#### `dis.findlinestarts(code)`166167Эта функция-генератор использует атрибуты `co_firstlineno` и `co_lnotab` объекта кода *code* для поиска смещений, соответствующих началам строк в исходном коде. Они генерируются как пары `(offset, lineno)`. Описание формата `co_lnotab` и способ его декодирования см. в [Objects/lnotab\_notes.txt](https://python-all.ru/src/3.8/Objects/lnotab_notes.txt).168169Изменено в версии 3.6: Номера строк могут уменьшаться. Раньше они всегда увеличивались.170171#### `dis.findlabels(code)`172173Обнаруживает все смещения в сырой скомпилированной строке байткода *code*, которые являются целями переходов, и возвращает список этих смещений.174175#### `dis.stack_effect(opcode, oparg=None, *, jump=None)`176177Вычисляет эффект стека для *opcode* с аргументом *oparg*.178179Если код имеет цель перехода и *jump* равен `True`, [`stack_effect()`](https://python-all.ru/3.8/library/dis.html#dis.stack_effect) возвращает эффект стека при переходе. Если *jump* равен `False`, возвращается эффект стека при отсутствии перехода. А если *jump* равен `None` (по умолчанию), возвращается максимальный эффект стека для обоих случаев.180181Новое в версии 3.4.182183Изменено в версии 3.8: Добавлен параметр *jump*.184185## Инструкции байткода Python186187Функция [`get_instructions()`](https://python-all.ru/3.8/library/dis.html#dis.get_instructions) и класс [`Bytecode`](https://python-all.ru/3.8/library/dis.html#dis.Bytecode) предоставляют сведения об инструкциях байткода в виде экземпляров [`Instruction`](https://python-all.ru/3.8/library/dis.html#dis.Instruction):188189#### `class dis.Instruction`190191Подробности об операции байткода192193#### `opcode`194195Числовой код операции, соответствующий значениям опкодов, перечисленным ниже, и значениям байткода в [коллекциях Opcode](https://python-all.ru/3.8/library/dis.html#opcode-collections).196197#### `opname`198199Человекочитаемое имя операции200201#### `arg`202203числовой аргумент операции (если есть), иначе `None`204205#### `argval`206207разрешённое значение аргумента (если известно), иначе то же, что и arg208209#### `argrepr`210211человекочитаемое описание аргумента операции212213#### `offset`214215начальный индекс операции в последовательности байт-кода216217#### `starts_line`218219Строка, с которой начинается данный опкод (если есть), иначе `None`.220221#### `is_jump_target`222223`True`, если другой код переходит сюда, иначе `False`224225Новое в версии 3.4.226227В настоящее время компилятор Python генерирует следующие инструкции байткода.228229**Общие инструкции**230231**`NOP`**232233Код, который ничего не делает. Используется в качестве заполнителя оптимизатором байт-кода.234235**`POP_TOP`**236237Удаляет элемент с вершины стека (TOS).238239**`ROT_TWO`**240241Меняет местами два верхних элемента стека.242243**`ROT_THREE`**244245Поднимает второй и третий элементы стека на одну позицию вверх, перемещает верхний вниз на третью позицию.246247**`ROT_FOUR`**248249Поднимает второй, третий и четвёртый элементы стека на одну позицию вверх, перемещает верхний вниз на четвёртую позицию.250251Новое в версии 3.8.252253**`DUP_TOP`**254255Дублирует ссылку на вершине стека.256257Новое в версии 3.2.258259**`DUP_TOP_TWO`**260261Дублирует две ссылки на вершине стека, сохраняя их порядок.262263Новое в версии 3.2.264265**Унарные операции**266267Унарные операции берут элемент с вершины стека, применяют операцию и помещают результат обратно на стек.268269**`UNARY_POSITIVE`**270271Реализует `TOS = +TOS`.272273**`UNARY_NEGATIVE`**274275Реализует `TOS = -TOS`.276277**`UNARY_NOT`**278279Реализует `TOS = not TOS`.280281**`UNARY_INVERT`**282283Реализует `TOS = ~TOS`.284285**`GET_ITER`**286287Реализует `TOS = iter(TOS)`.288289**`GET_YIELD_FROM_ITER`**290291Если `TOS` является объектом [генераторный итератор](https://python-all.ru/3.8/glossary.html#term-generator-iterator) или [корутина](https://python-all.ru/3.8/glossary.html#term-coroutine), он остаётся без изменений. В противном случае реализует `TOS = iter(TOS)`.292293Новое в версии 3.5.294295**Бинарные операции**296297Бинарные операции удаляют из стека элемент с вершины (TOS) и второй сверху элемент стека (TOS1). Они выполняют операцию и помещают результат обратно в стек.298299**`BINARY_POWER`**300301Реализует `TOS = TOS1 ** TOS`.302303**`BINARY_MULTIPLY`**304305Реализует `TOS = TOS1 * TOS`.306307**`BINARY_MATRIX_MULTIPLY`**308309Реализует `TOS = TOS1 @ TOS`.310311Новое в версии 3.5.312313**`BINARY_FLOOR_DIVIDE`**314315Реализует `TOS = TOS1 // TOS`.316317**`BINARY_TRUE_DIVIDE`**318319Реализует `TOS = TOS1 / TOS`.320321**`BINARY_MODULO`**322323Реализует `TOS = TOS1 % TOS`.324325**`BINARY_ADD`**326327Реализует `TOS = TOS1 + TOS`.328329**`BINARY_SUBTRACT`**330331Реализует `TOS = TOS1 - TOS`.332333**`BINARY_SUBSCR`**334335Реализует `TOS = TOS1[TOS]`.336337**`BINARY_LSHIFT`**338339Реализует `TOS = TOS1 << TOS`.340341**`BINARY_RSHIFT`**342343Реализует `TOS = TOS1 >> TOS`.344345**`BINARY_AND`**346347Реализует `TOS = TOS1 & TOS`.348349**`BINARY_XOR`**350351Реализует `TOS = TOS1 ^ TOS`.352353**`BINARY_OR`**354355Реализует `TOS = TOS1 | TOS`.356357**Операции на месте**358359Операции на месте аналогичны бинарным: они также удаляют TOS и TOS1 и помещают результат обратно в стек, но операция выполняется на месте, если TOS1 это поддерживает, и результирующий TOS может (но не обязан) быть исходным TOS1.360361**`INPLACE_POWER`**362363Реализует операцию на месте `TOS = TOS1 ** TOS`.364365**`INPLACE_MULTIPLY`**366367Реализует операцию на месте `TOS = TOS1 * TOS`.368369**`INPLACE_MATRIX_MULTIPLY`**370371Реализует операцию на месте `TOS = TOS1 @ TOS`.372373Новое в версии 3.5.374375**`INPLACE_FLOOR_DIVIDE`**376377Реализует операцию на месте `TOS = TOS1 // TOS`.378379**`INPLACE_TRUE_DIVIDE`**380381Реализует операцию на месте `TOS = TOS1 / TOS`.382383**`INPLACE_MODULO`**384385Реализует операцию на месте `TOS = TOS1 % TOS`.386387**`INPLACE_ADD`**388389Реализует операцию на месте `TOS = TOS1 + TOS`.390391**`INPLACE_SUBTRACT`**392393Реализует операцию на месте `TOS = TOS1 - TOS`.394395**`INPLACE_LSHIFT`**396397Реализует операцию на месте `TOS = TOS1 << TOS`.398399**`INPLACE_RSHIFT`**400401Реализует операцию на месте `TOS = TOS1 >> TOS`.402403**`INPLACE_AND`**404405Реализует операцию на месте `TOS = TOS1 & TOS`.406407**`INPLACE_XOR`**408409Реализует операцию на месте `TOS = TOS1 ^ TOS`.410411**`INPLACE_OR`**412413Реализует операцию на месте `TOS = TOS1 | TOS`.414415**`STORE_SUBSCR`**416417Реализует `TOS1[TOS] = TOS2`.418419**`DELETE_SUBSCR`**420421Реализует `del TOS1[TOS]`.422423**Коды операций корутин**424425**`GET_AWAITABLE`**426427Реализует `TOS = get_awaitable(TOS)`, где `get_awaitable(o)` возвращает `o`, если `o` является объектом корутины или объектом генератора с флагом CO\_ITERABLE\_COROUTINE, или разрешает `o.__await__`.428429Новое в версии 3.5.430431**`GET_AITER`**432433Реализует `TOS = TOS.__aiter__()`.434435Новое в версии 3.5.436437Изменено в версии 3.7: Возврат ожидаемых объектов из `__aiter__` больше не поддерживается.438439**`GET_ANEXT`**440441Реализует `PUSH(get_awaitable(TOS.__anext__()))`. Подробнее о `get_awaitable` см. в `GET_AWAITABLE`.442443Новое в версии 3.5.444445**`END_ASYNC_FOR`**446447Завершает цикл [`async for`](https://python-all.ru/3.8/reference/compound_stmts.html#async-for). Обрабатывает исключение, возникшее при ожидании следующего элемента. Если TOS равно [`StopAsyncIteration`](https://python-all.ru/3.8/library/exceptions.html#StopAsyncIteration), извлекает 7 значений из стека и восстанавливает состояние исключения, используя вторые три из них. В противном случае повторно возбуждает исключение, используя три значения из стека. Блок обработчика исключения удаляется из стека блоков.448449Новое в версии 3.8.450451**`BEFORE_ASYNC_WITH`**452453Извлекает `__aenter__` и `__aexit__` из объекта на вершине стека. Помещает `__aexit__` и результат `__aenter__()` в стек.454455Новое в версии 3.5.456457**`SETUP_ASYNC_WITH`**458459Создаёт новый объект фрейма.460461Новое в версии 3.5.462463**Прочие опкоды**464465**`PRINT_EXPR`**466467Реализует выражение-инструкцию для интерактивного режима. TOS удаляется из стека и выводится на печать. В неинтерактивном режиме выражение-инструкция завершается с помощью [`POP_TOP`](https://python-all.ru/3.8/library/dis.html#opcode-POP_TOP).468469**`SET_ADD`(*i*)**470471Вызывает `set.add(TOS1[-i], TOS)`. Используется для реализации множественных включений (set comprehensions).472473**`LIST_APPEND`(*i*)**474475Вызывает `list.append(TOS1[-i], TOS)`. Используется для реализации списковых включений (list comprehensions).476477**`MAP_ADD`(*i*)**478479Вызывает `dict.__setitem__(TOS1[-i], TOS1, TOS)`. Используется для реализации словарных включений (dict comprehensions).480481Новое в версии 3.1.482483Изменено в версии 3.8: Значением отображения теперь является TOS, а ключом – TOS1. Ранее они были переставлены.484485Для всех инструкций [`SET_ADD`](https://python-all.ru/3.8/library/dis.html#opcode-SET_ADD), [`LIST_APPEND`](https://python-all.ru/3.8/library/dis.html#opcode-LIST_APPEND) и [`MAP_ADD`](https://python-all.ru/3.8/library/dis.html#opcode-MAP_ADD), когда добавленное значение или пара ключ/значение извлекаются, объект-контейнер остаётся в стеке, чтобы быть доступным для последующих итераций цикла.486487**`RETURN_VALUE`**488489Возвращает TOS вызывающей стороне функции.490491**`YIELD_VALUE`**492493Извлекает TOS и возвращает его из [генератора](https://python-all.ru/3.8/glossary.html#term-generator).494495**`YIELD_FROM`**496497Извлекает TOS и делегирует ему как под-итератор от [генератора](https://python-all.ru/3.8/glossary.html#term-generator).498499Новое в версии 3.3.500501**`SETUP_ANNOTATIONS`**502503Проверяет, определён ли `__annotations__` в `locals()`; если нет, он устанавливается в пустой `dict`. Этот опкод генерируется, только если тело класса или модуля статически содержит [аннотации переменных](https://python-all.ru/3.8/glossary.html#term-variable-annotation).504505Новое в версии 3.6.506507**`IMPORT_STAR`**508509Загружает все имена, не начинающиеся с `'_'`, из модуля TOS в локальное пространство имён. Модуль удаляется после загрузки всех имён. Этот опкод реализует `from module import *`.510511**`POP_BLOCK`**512513Удаляет один блок из стека блоков. Для каждого фрейма существует стек блоков, обозначающий операторы [`try`](https://python-all.ru/3.8/reference/compound_stmts.html#try) и тому подобное.514515**`POP_EXCEPT`**516517Удаляет один блок из стека блоков. Извлечённый блок должен быть блоком обработчика исключения, неявно создаваемым при входе в обработчик except. Помимо извлечения лишних значений из стека фрейма, последние три извлечённых значения используются для восстановления состояния исключения.518519**`POP_FINALLY`(*preserve\_tos*)**520521Очищает стек значений и стек блоков. Если *preserve\_tos* не `0`, сначала TOS извлекается из стека и помещается обратно после выполнения других операций со стеком:522523- Если TOS равен `NULL` или целому числу (помещено с помощью [`BEGIN_FINALLY`](https://python-all.ru/3.8/library/dis.html#opcode-BEGIN_FINALLY) или [`CALL_FINALLY`](https://python-all.ru/3.8/library/dis.html#opcode-CALL_FINALLY)), он извлекается из стека.524- Если TOS является типом исключения (помещён, когда было возбуждено исключение), из стека извлекаются 6 значений, последние три извлечённых значения используются для восстановления состояния исключения. Блок обработчика исключения удаляется из стека блоков.525526Он похож на [`END_FINALLY`](https://python-all.ru/3.8/library/dis.html#opcode-END_FINALLY), но не изменяет счётчик байткода и не возбуждает исключение. Используется для реализации [`break`](https://python-all.ru/3.8/reference/simple_stmts.html#break), [`continue`](https://python-all.ru/3.8/reference/simple_stmts.html#continue) и [`return`](https://python-all.ru/3.8/reference/simple_stmts.html#return) в блоке [`finally`](https://python-all.ru/3.8/reference/compound_stmts.html#finally).527528Новое в версии 3.8.529530**`BEGIN_FINALLY`**531532Помещает `NULL` в стек для использования в [`END_FINALLY`](https://python-all.ru/3.8/library/dis.html#opcode-END_FINALLY), [`POP_FINALLY`](https://python-all.ru/3.8/library/dis.html#opcode-POP_FINALLY), [`WITH_CLEANUP_START`](https://python-all.ru/3.8/library/dis.html#opcode-WITH_CLEANUP_START) и [`WITH_CLEANUP_FINISH`](https://python-all.ru/3.8/library/dis.html#opcode-WITH_CLEANUP_FINISH). Начинает блок [`finally`](https://python-all.ru/3.8/reference/compound_stmts.html#finally).533534Новое в версии 3.8.535536**`END_FINALLY`**537538Завершает конструкцию [`finally`](https://python-all.ru/3.8/reference/compound_stmts.html#finally). Интерпретатор запоминает, нужно ли повторно возбуждать исключение или продолжить выполнение в зависимости от значения TOS.539540- Если TOS равен `NULL` (помещён с помощью [`BEGIN_FINALLY`](https://python-all.ru/3.8/library/dis.html#opcode-BEGIN_FINALLY)), продолжить со следующей инструкции. TOS извлекается.541- Если TOS является целым числом (помещено с помощью [`CALL_FINALLY`](https://python-all.ru/3.8/library/dis.html#opcode-CALL_FINALLY)), устанавливает счётчик байткода в TOS. TOS извлекается.542- Если TOS является типом исключения (помещён, когда было возбуждено исключение), из стека извлекаются 6 значений, первые три извлечённых значения используются для повторного возбуждения исключения, а последние три извлечённых значения используются для восстановления состояния исключения. Блок обработчика исключения удаляется из стека блоков.543544**`LOAD_BUILD_CLASS`**545546Помещает `builtins.__build_class__()` в стек. Позже он вызывается [`CALL_FUNCTION`](https://python-all.ru/3.8/library/dis.html#opcode-CALL_FUNCTION) для создания класса.547548**`SETUP_WITH`(*delta*)**549550Этот опкод выполняет несколько операций перед началом блока with. Сначала он загружает [`__exit__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__exit__) из контекстного менеджера и помещает его в стек для последующего использования [`WITH_CLEANUP_START`](https://python-all.ru/3.8/library/dis.html#opcode-WITH_CLEANUP_START). Затем вызывается [`__enter__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__enter__), и помещается блок finally, указывающий на *delta*. Наконец, результат вызова метода `__enter__()` помещается в стек. Следующий опкод либо игнорирует его ([`POP_TOP`](https://python-all.ru/3.8/library/dis.html#opcode-POP_TOP)), либо сохраняет в переменную(ые) ([`STORE_FAST`](https://python-all.ru/3.8/library/dis.html#opcode-STORE_FAST), [`STORE_NAME`](https://python-all.ru/3.8/library/dis.html#opcode-STORE_NAME) или [`UNPACK_SEQUENCE`](https://python-all.ru/3.8/library/dis.html#opcode-UNPACK_SEQUENCE)).551552Новое в версии 3.2.553554**`WITH_CLEANUP_START`**555556Начинает очистку стека при выходе из блока оператора [`with`](https://python-all.ru/3.8/reference/compound_stmts.html#with).557558В верхней части стека находятся либо `NULL` (помещён с помощью [`BEGIN_FINALLY`](https://python-all.ru/3.8/library/dis.html#opcode-BEGIN_FINALLY)), либо 6 значений, помещённых, если в блоке with было возбуждено исключение. Ниже находится привязанный метод [`__exit__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__exit__) или [`__aexit__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__aexit__) менеджера контекста.559560Если TOS равен `NULL`, вызывает `SECOND(None, None, None)`, удаляет функцию из стека, оставляя TOS, и помещает `None` в стек. В противном случае вызывает `SEVENTH(TOP, SECOND, THIRD)`, сдвигает нижние 3 значения стека вниз, заменяет пустое место на `NULL` и помещает TOS. Наконец помещает результат вызова.561562**`WITH_CLEANUP_FINISH`**563564Завершает очистку стека при выходе из блока оператора [`with`](https://python-all.ru/3.8/reference/compound_stmts.html#with).565566TOS – это результат вызова функции `__exit__()` или `__aexit__()`, помещённый с помощью [`WITH_CLEANUP_START`](https://python-all.ru/3.8/library/dis.html#opcode-WITH_CLEANUP_START). SECOND – это `None` или тип исключения (помещён, когда было возбуждено исключение).567568Извлекает два значения из стека. Если SECOND не None и TOS истинно, разворачивает блок EXCEPT\_HANDLER, который был создан при перехвате исключения, и помещает `NULL` в стек.569570Все следующие опкоды используют свои аргументы.571572**`STORE_NAME`(*namei*)**573574Реализует `name = TOS`. *namei* – это индекс *name* в атрибуте `co_names` объекта кода. Компилятор пытается использовать [`STORE_FAST`](https://python-all.ru/3.8/library/dis.html#opcode-STORE_FAST) или [`STORE_GLOBAL`](https://python-all.ru/3.8/library/dis.html#opcode-STORE_GLOBAL), если это возможно.575576**`DELETE_NAME`(*namei*)**577578Реализует `del name`, где *namei* – это индекс в атрибут `co_names` объекта кода.579580**`UNPACK_SEQUENCE`(*count*)**581582Распаковывает TOS в *count* отдельных значений, которые помещаются в стек справа налево.583584**`UNPACK_EX`(*counts*)**585586Реализует присваивание со звёздочкой: распаковывает итерируемый объект в TOS на отдельные значения, где общее количество значений может быть меньше количества элементов в итерируемом объекте: одно из новых значений будет списком всех оставшихся элементов.587588Младший байт *counts* – это количество значений до спискового значения, а старший байт *counts* – количество значений после него. Результирующие значения помещаются в стек справа налево.589590**`STORE_ATTR`(*namei*)**591592Реализует `TOS.name = TOS1`, где *namei* – это индекс имени в `co_names`.593594**`DELETE_ATTR`(*namei*)**595596Реализует `del TOS.name`, используя *namei* как индекс в `co_names`.597598**`STORE_GLOBAL`(*namei*)**599600Работает как [`STORE_NAME`](https://python-all.ru/3.8/library/dis.html#opcode-STORE_NAME), но сохраняет имя как глобальное.601602**`DELETE_GLOBAL`(*namei*)**603604Работает как [`DELETE_NAME`](https://python-all.ru/3.8/library/dis.html#opcode-DELETE_NAME), но удаляет глобальное имя.605606**`LOAD_CONST`(*consti*)**607608Помещает `co_consts[consti]` в стек.609610**`LOAD_NAME`(*namei*)**611612Помещает значение, связанное с `co_names[namei]`, в стек.613614**`BUILD_TUPLE`(*count*)**615616Создаёт кортеж, потребляя *count* элементов из стека, и помещает полученный кортеж в стек.617618**`BUILD_LIST`(*count*)**619620Работает как [`BUILD_TUPLE`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_TUPLE), но создаёт список.621622**`BUILD_SET`(*count*)**623624Работает как [`BUILD_TUPLE`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_TUPLE), но создаёт множество.625626**`BUILD_MAP`(*count*)**627628Помещает новый объект словаря в стек. Извлекает `2 * count` элементов так, чтобы словарь содержал *count* записей: `{..., TOS3: TOS2, TOS1: TOS}`.629630Изменено в версии 3.5: Словарь создаётся из элементов стека, а не создаётся пустой словарь, предварительно размещённый для *count* элементов.631632**`BUILD_CONST_KEY_MAP`(*count*)**633634Версия [`BUILD_MAP`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_MAP), оптимизированная для константных ключей. Снимает верхний элемент стека, содержащий кортеж ключей, затем, начиная с `TOS1`, снимает *count* значений и формирует словарь.635636Новое в версии 3.6.637638**`BUILD_STRING`(*count*)**639640Конкатенирует *count* строк из стека и помещает результирующую строку в стек.641642Новое в версии 3.6.643644**`BUILD_TUPLE_UNPACK`(*count*)**645646Извлекает *count* итерируемых объектов из стека, объединяет их в один кортеж, и помещает результат. Реализует распаковку итерируемого объекта в кортежных литералах `(*x, *y, *z)`.647648Новое в версии 3.5.649650**`BUILD_TUPLE_UNPACK_WITH_CALL`(*count*)**651652Это похоже на [`BUILD_TUPLE_UNPACK`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_TUPLE_UNPACK), но используется для синтаксиса вызова `f(*x, *y, *z)`. Элемент стека на позиции `count + 1` должен быть соответствующим вызываемым объектом `f`.653654Новое в версии 3.6.655656**`BUILD_LIST_UNPACK`(*count*)**657658Это похоже на [`BUILD_TUPLE_UNPACK`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_TUPLE_UNPACK), но помещает список, а не кортеж. Реализует распаковку итерируемого объекта в списковых литералах `[*x, *y, *z]`.659660Новое в версии 3.5.661662**`BUILD_SET_UNPACK`(*count*)**663664Это похоже на [`BUILD_TUPLE_UNPACK`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_TUPLE_UNPACK), но помещает множество, а не кортеж. Реализует распаковку итерируемого объекта в множественных литералах `{*x, *y, *z}`.665666Новое в версии 3.5.667668**`BUILD_MAP_UNPACK`(*count*)**669670Извлекает *count* отображений из стека, объединяет их в один словарь и помещает результат. Реализует распаковку словаря в словарных литералах `{**x, **y, **z}`.671672Новое в версии 3.5.673674**`BUILD_MAP_UNPACK_WITH_CALL`(*count*)**675676Это похоже на [`BUILD_MAP_UNPACK`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_MAP_UNPACK), но используется для синтаксиса вызова `f(**x, **y, **z)`. Элемент стека на позиции `count + 2` должен быть соответствующим вызываемым объектом `f`.677678Новое в версии 3.5.679680Изменено в версии 3.6: Позиция вызываемого объекта определяется прибавлением 2 к аргументу кода операции, а не кодированием её во втором байте аргумента.681682**`LOAD_ATTR`(*namei*)**683684Заменяет TOS на `getattr(TOS, co_names[namei])`.685686**`COMPARE_OP`(*opname*)**687688Выполняет логическую операцию. Имя операции можно найти в `cmp_op[opname]`.689690**`IMPORT_NAME`(*namei*)**691692Импортирует модуль `co_names[namei]`. TOS и TOS1 извлекаются и передаются в качестве аргументов *fromlist* и *level* для [`__import__()`](https://python-all.ru/3.8/library/functions.html#__import__). Объект модуля помещается в стек. Текущее пространство имён не затрагивается: для корректной инструкции import последующая инструкция [`STORE_FAST`](https://python-all.ru/3.8/library/dis.html#opcode-STORE_FAST) изменяет пространство имён.693694**`IMPORT_FROM`(*namei*)**695696Загружает атрибут `co_names[namei]` из модуля, находящегося в TOS. Полученный объект помещается в стек для последующего сохранения инструкцией [`STORE_FAST`](https://python-all.ru/3.8/library/dis.html#opcode-STORE_FAST).697698**`JUMP_FORWARD`(*delta*)**699700Увеличивает счётчик байт-кода на *delta*.701702**`POP_JUMP_IF_TRUE`(*target*)**703704Если TOS истинно, устанавливает счётчик байткода в *target*. TOS извлекается из стека.705706Новое в версии 3.1.707708**`POP_JUMP_IF_FALSE`(*target*)**709710Если TOS ложно, устанавливает счётчик байткода в *target*. TOS извлекается из стека.711712Новое в версии 3.1.713714**`JUMP_IF_TRUE_OR_POP`(*target*)**715716Если TOS истинно, устанавливает счётчик байткода в *target* и оставляет TOS на стеке. В противном случае (TOS ложно) TOS извлекается.717718Новое в версии 3.1.719720**`JUMP_IF_FALSE_OR_POP`(*target*)**721722Если TOS ложно, устанавливает счётчик байткода в *target* и оставляет TOS на стеке. В противном случае (TOS истинно) TOS извлекается.723724Новое в версии 3.1.725726**`JUMP_ABSOLUTE`(*target*)**727728Устанавливает счётчик байткода в *target*.729730**`FOR_ITER`(*delta*)**731732TOS – это [итератор](https://python-all.ru/3.8/glossary.html#term-iterator). Вызовите его метод [`__next__()`](https://python-all.ru/3.8/library/stdtypes.html#iterator.__next__). Если он возвращает новое значение, поместите его в стек (итератор остаётся под ним). Если итератор сообщает, что он исчерпан, TOS извлекается из стека, а счётчик байт-кода увеличивается на *delta*.733734**`LOAD_GLOBAL`(*namei*)**735736Загружает глобальную переменную `co_names[namei]` в стек.737738**`SETUP_FINALLY`(*delta*)**739740Помещает блок try из предложения try-finally или try-except на стек блоков. *delta* указывает на блок finally или первый блок except.741742**`CALL_FINALLY`(*delta*)**743744Помещает адрес следующей инструкции в стек и увеличивает счётчик байт-кода на *delta*. Используется для вызова блока finally как «подпрограммы».745746Новое в версии 3.8.747748**`LOAD_FAST`(*var\_num*)**749750Помещает ссылку на локальную переменную `co_varnames[var_num]` в стек.751752**`STORE_FAST`(*var\_num*)**753754Сохраняет TOS в локальную переменную `co_varnames[var_num]`.755756**`DELETE_FAST`(*var\_num*)**757758Удаляет локальную переменную `co_varnames[var_num]`.759760**`LOAD_CLOSURE`(*i*)**761762Помещает ссылку на ячейку, содержащуюся в слоте *i* хранилища ячеек и свободных переменных. Имя переменной – `co_cellvars[i]`, если *i* меньше длины *co\_cellvars*. В противном случае – `co_freevars[i - len(co_cellvars)]`.763764**`LOAD_DEREF`(*i*)**765766Загружает ячейку, содержащуюся в слоте *i* хранилища ячеек и свободных переменных. Помещает ссылку на объект, который содержит ячейка, в стек.767768**`LOAD_CLASSDEREF`(*i*)**769770Похожа на [`LOAD_DEREF`](https://python-all.ru/3.8/library/dis.html#opcode-LOAD_DEREF), но сначала проверяет словарь локальных переменных, а затем обращается к ячейке. Используется для загрузки свободных переменных в телах классов.771772Новое в версии 3.4.773774**`STORE_DEREF`(*i*)**775776Сохраняет TOS в ячейку, содержащуюся в слоте *i* хранилища ячеек и свободных переменных.777778**`DELETE_DEREF`(*i*)**779780Очищает ячейку, содержащуюся в слоте *i* хранилища ячеек и свободных переменных. Используется оператором [`del`](https://python-all.ru/3.8/reference/simple_stmts.html#del).781782Новое в версии 3.2.783784**`RAISE_VARARGS`(*argc*)**785786Вызывает исключение, используя одну из трёх форм оператора `raise`, в зависимости от значения *argc*:787788- 0: `raise` (повторный вызов предыдущего исключения)789- 1: `raise TOS` (вызов экземпляра или типа исключения по адресу `TOS`)790- 2: `raise TOS1 from TOS` (возбуждает экземпляр или тип исключения на `TOS1` с `__cause__` установленным в `TOS`)791792**`CALL_FUNCTION`(*argc*)**793794Вызывает вызываемый объект с позиционными аргументами. *argc* указывает количество позиционных аргументов. Вершина стека содержит позиционные аргументы, причём самый правый аргумент находится на вершине. Под аргументами находится вызываемый объект. `CALL_FUNCTION` извлекает все аргументы и вызываемый объект из стека, вызывает вызываемый объект с этими аргументами и помещает возвращаемое значение, возвращённое вызываемым объектом, в стек.795796Изменено в версии 3.6: Эта инструкция используется только для вызовов с позиционными аргументами.797798**`CALL_FUNCTION_KW`(*argc*)**799800Вызывает вызываемый объект с позиционными (если есть) и именованными аргументами. *argc* указывает общее количество позиционных и именованных аргументов. Верхний элемент стека содержит кортеж имён именованных аргументов. Под ним находятся именованные аргументы в порядке, соответствующем кортежу. Под ними – позиционные аргументы, причём самый правый параметр – наверху. Под аргументами находится вызываемый объект. `CALL_FUNCTION_KW` извлекает все аргументы и вызываемый объект из стека, вызывает вызываемый объект с этими аргументами и помещает возвращаемое значение, возвращённое вызываемым объектом, обратно в стек.801802Изменено в версии 3.6: Именованные аргументы упаковываются в кортеж вместо словаря, *argc* указывает общее количество аргументов.803804**`CALL_FUNCTION_EX`(*flags*)**805806Вызывает вызываемый объект с переменным набором позиционных и именованных аргументов. Если установлен младший бит *flags*, верхний элемент стека содержит объект отображения (mapping) с дополнительными именованными аргументами. Под ним находится итерируемый объект, содержащий позиционные аргументы и вызываемый объект. [`BUILD_MAP_UNPACK_WITH_CALL`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_MAP_UNPACK_WITH_CALL) и [`BUILD_TUPLE_UNPACK_WITH_CALL`](https://python-all.ru/3.8/library/dis.html#opcode-BUILD_TUPLE_UNPACK_WITH_CALL) можно использовать для объединения нескольких объектов отображения и итерируемых объектов с аргументами. Перед вызовом вызываемого объекта объект отображения и итерируемый объект «распаковываются», и их содержимое передаётся как именованные и позиционные аргументы соответственно. `CALL_FUNCTION_EX` извлекает все аргументы и вызываемый объект из стека, вызывает вызываемый объект с этими аргументами и помещает возвращаемое значение, возвращённое вызываемым объектом, обратно в стек.807808Новое в версии 3.6.809810**`LOAD_METHOD`(*namei*)**811812Загружает метод с именем `co_names[namei]` из объекта TOS. TOS удаляется из стека. Этот байт-код различает два случая: если TOS имеет метод с правильным именем, он помещает в стек несвязанный метод и TOS. TOS будет использоваться как первый аргумент (`self`) в [`CALL_METHOD`](https://python-all.ru/3.8/library/dis.html#opcode-CALL_METHOD) при вызове несвязанного метода. В противном случае помещаются `NULL` и объект, возвращённый поиском атрибута.813814Добавлено в версии 3.7.815816**`CALL_METHOD`(*argc*)**817818Вызывает метод. *argc* – количество позиционных аргументов. Именованные аргументы не поддерживаются. Эта инструкция предназначена для использования с [`LOAD_METHOD`](https://python-all.ru/3.8/library/dis.html#opcode-LOAD_METHOD). Позиционные аргументы находятся на вершине стека. Под ними находятся два элемента, описанные в [`LOAD_METHOD`](https://python-all.ru/3.8/library/dis.html#opcode-LOAD_METHOD) (либо `self` и несвязанный метод, либо `NULL` и произвольный вызываемый объект). Все они извлекаются, и возвращаемое значение помещается в стек.819820Добавлено в версии 3.7.821822**`MAKE_FUNCTION`(*flags*)**823824Помещает новый объект функции в стек. Снизу вверх потребляемый стек должен состоять из значений, если аргумент содержит указанное значение флага.825826- `0x01` кортеж значений по умолчанию для только-позиционных и позиционно-именованных параметров в позиционном порядке827- `0x02` словарь значений по умолчанию только-именованных параметров828- `0x04` словарь аннотаций829- `0x08` кортеж, содержащий ячейки для свободных переменных, образующий замыкание830- код, связанный с функцией (на TOS1)831- [полное имя](https://python-all.ru/3.8/glossary.html#term-qualified-name) функции (на TOS)832833**`BUILD_SLICE`(*argc*)**834835Помещает объект среза в стек. *argc* должен быть 2 или 3. Если равно 2, помещается `slice(TOS1, TOS)`; если 3, помещается `slice(TOS2, TOS1, TOS)`. Подробнее см. встроенную функцию [`slice()`](https://python-all.ru/3.8/library/functions.html#slice).836837**`EXTENDED_ARG`(*ext*)**838839Является префиксом для любой операции, аргумент которой слишком велик, чтобы поместиться в один байт по умолчанию. *ext* содержит дополнительный байт, который выступает в качестве старших битов аргумента. Для каждой операции допускается не более трёх префиксов `EXTENDED_ARG`, формирующих аргумент от двух до четырёх байт.840841**`FORMAT_VALUE`(*flags*)**842843Используется для реализации форматированных строковых литералов (f-строк). Извлекает из стека необязательную *спецификацию формата*, затем обязательное *значение*. *Флаги* интерпретируются следующим образом:844845- `(flags & 0x03) == 0x00`: *значение* форматируется как есть.846- `(flags & 0x03) == 0x01`: извлечь [спецификацию формата](https://python-all.ru/3.8/library/stdtypes.html#str) из стека и использовать её, иначе использовать пустую *спецификацию формата*.847- `(flags & 0x03) == 0x02`: извлечь [спецификацию формата](https://python-all.ru/3.8/library/functions.html#repr) из стека и использовать её, иначе использовать пустую *спецификацию формата*.848- `(flags & 0x03) == 0x03`: извлечь [спецификацию формата](https://python-all.ru/3.8/library/functions.html#ascii) из стека и использовать её, иначе использовать пустую *спецификацию формата*.849- `(flags & 0x04) == 0x04`: извлечь *fmt\_spec* из стека и использовать его, иначе использовать пустой *fmt\_spec*.850851Форматирование выполняется с помощью `PyObject_Format()`. Результат помещается в стек.852853Новое в версии 3.6.854855**`HAVE_ARGUMENT`**856857Это не совсем опкод. Он обозначает границу между опкодами, которые не используют свой аргумент, и теми, которые используют (соответственно `< HAVE_ARGUMENT` и `>= HAVE_ARGUMENT`).858859Изменено в версии 3.6: Теперь каждая инструкция имеет аргумент, но опкоды `< HAVE_ARGUMENT` игнорируют его. Раньше аргумент был только у опкодов `>= HAVE_ARGUMENT`.860861## Коллекции опкодов862863Эти коллекции предоставляются для автоматического самоанализа инструкций байткода:864865#### `dis.opname`866867Последовательность имён операций, индексируемая с помощью байткода.868869#### `dis.opmap`870871Словарь, сопоставляющий имена операций с байткодами.872873#### `dis.cmp_op`874875Последовательность всех имён операций сравнения.876877#### `dis.hasconst`878879Последовательность байткодов, обращающихся к константе.880881#### `dis.hasfree`882883Последовательность байткодов, которые обращаются к свободной переменной (обратите внимание, что «free» в данном контексте относится к именам в текущей области видимости, на которые ссылаются внутренние области видимости, или к именам во внешних областях видимости, на которые ссылаются из этой области. Она *не* включает ссылки на глобальные или встроенные области видимости).884885#### `dis.hasname`886887Последовательность байткодов, обращающихся к атрибуту по имени.888889#### `dis.hasjrel`890891Последовательность байткодов, имеющих относительную цель перехода.892893#### `dis.hasjabs`894895Последовательность байткодов, имеющих абсолютную цель перехода.896897#### `dis.haslocal`898899Последовательность байткодов, обращающихся к локальной переменной.900901#### `dis.hascompare`902903Последовательность байткодов логических операций.904