dis.md
1> **Источник:** https://python-all.ru/3.0/library/dis.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `dis` – Дисассемблер байт-кода Python89Модуль `dis` поддерживает анализ Python [*байт-кода*](https://python-all.ru/3.0/glossary.html#term-bytecode) путём его дизассемблирования. Поскольку ассемблера для Python не существует, этот модуль определяет язык ассемблера Python. Байт-код Python, который подаётся на вход этому модулю, определён в файле `Include/opcode.h` и используется компилятором и интерпретатором.1011Пример: дана функция `myfunc()`:1213```python14def myfunc(alist):15 return len(alist)16```1718Для получения дизассемблированного кода `myfunc()` можно использовать следующую команду:1920```python21>>> dis.dis(myfunc)22 2 0 LOAD_GLOBAL 0 (len)23 3 LOAD_FAST 0 (alist)24 6 CALL_FUNCTION 125 9 RETURN_VALUE26```2728(«2» – это номер строки).2930Модуль `dis` определяет следующие функции и константы:3132#### `[dis.dis]dis.dis([bytesource])`3334Дизассемблирует объект3536*bytesource*3738.3940*bytesource*4142может обозначать модуль, класс, метод, функцию или объект кода. Для модуля дизассемблируются все функции. Для класса – все методы. Для одной последовательности кода выводится одна строка на каждую инструкцию байт-кода. Если объект не указан, дизассемблируется последняя трассировка.4344#### `[dis.distb]dis.distb([tb])`4546Дизассемблирует функцию на вершине стека трассировки, используя последнюю трассировку, если ни одна не была передана. Указывается инструкция, вызвавшая исключение.4748#### `[dis.disassemble]dis.disassemble(code[, lasti])`4950Дизассемблирует объект кода, указывая последнюю инструкцию, если был указан *lasti*. Вывод разделён на следующие столбцы:51521. номер строки для первой инструкции каждой строки532. текущая инструкция, помечена как `-->`,543. инструкция с меткой, помечена `>>`,554. адрес инструкции,565. название кода операции,576. параметры операции и587. интерпретация параметров в скобках.5960Интерпретация параметров распознаёт имена локальных и глобальных переменных, константные значения, цели переходов и операторы сравнения.6162#### `[dis.disco]dis.disco(code[, lasti])`6364Синоним для6566[`disassemble()`](https://python-all.ru/3.0/library/dis.html#dis.disassemble)6768. Его проще набирать, и он сохранён для совместимости с более ранними версиями Python.6970#### `[dis.findlinestarts]dis.findlinestarts(code)`7172Эта функция-генератор использует атрибуты7374`co_firstlineno`7576и7778`co_lnotab`7980объекта кода8182*code*8384для поиска смещений, соответствующих началам строк в исходном коде. Они генерируются в виде пар8586`(offset, lineno)`8788.8990#### `[dis.findlabels]dis.findlabels(code)`9192Определяет все смещения в объекте кода9394*code*9596, которые являются целями перехода, и\\nвозвращает список этих смещений.9798#### `[dis.opname]dis.opname`99100Последовательность имён операций, индексируемая с помощью байткода.101102#### `[dis.opmap]dis.opmap`103104Словарь, отображающий байт-коды в имена операций.105106#### `[dis.cmp_op]dis.cmp_op`107108Последовательность всех имён операций сравнения.109110#### `[dis.hasconst]dis.hasconst`111112Последовательность байткодов, имеющих постоянный параметр.113114#### `[dis.hasfree]dis.hasfree`115116Последовательность байткодов, обращающихся к свободной переменной.117118#### `[dis.hasname]dis.hasname`119120Последовательность байткодов, обращающихся к атрибуту по имени.121122#### `[dis.hasjrel]dis.hasjrel`123124Последовательность байткодов, имеющих относительную цель перехода.125126#### `[dis.hasjabs]dis.hasjabs`127128Последовательность байткодов, имеющих абсолютную цель перехода.129130#### `[dis.haslocal]dis.haslocal`131132Последовательность байткодов, обращающихся к локальной переменной.133134#### `[dis.hascompare]dis.hascompare`135136Последовательность байткодов логических операций.137138## Инструкции байткода Python139140В настоящее время компилятор Python генерирует следующие инструкции байткода.141142**`STOP_CODE`()**143144Указывает компилятору на конец кода, не используется интерпретатором.145146**`NOP`()**147148Код, который ничего не делает. Используется в качестве заполнителя оптимизатором байт-кода.149150**`POP_TOP`()**151152Удаляет элемент с вершины стека (TOS).153154**`ROT_TWO`()**155156Меняет местами два верхних элемента стека.157158**`ROT_THREE`()**159160Поднимает второй и третий элементы стека на одну позицию вверх, перемещает верхний вниз на третью позицию.161162**`ROT_FOUR`()**163164Поднимает второй, третий и четвёртый элементы стека на одну позицию вверх, перемещает верхний элемент вниз на четвёртую позицию.165166**`DUP_TOP`()**167168Дублирует ссылку на вершине стека.169170Унарные операции берут верхушку стека, применяют операцию и помещают результат обратно в стек.171172**`UNARY_POSITIVE`()**173174Реализует175176`TOS = +TOS`177178.179180**`UNARY_NEGATIVE`()**181182Реализует183184`TOS = -TOS`185186.187188**`UNARY_NOT`()**189190Реализует191192`TOS = не TOS`193194.195196**`UNARY_INVERT`()**197198Реализует199200`TOS = ~TOS`201202.203204**`GET_ITER`()**205206Реализует207208`TOS = iter(TOS)`209210.211212Бинарные операции удаляют из стека элемент с вершины (TOS) и второй сверху элемент стека (TOS1). Они выполняют операцию и помещают результат обратно в стек.213214**`BINARY_POWER`()**215216Реализует217218`TOS = TOS1 ** TOS`219220.221222**`BINARY_MULTIPLY`()**223224Реализует225226`TOS = TOS1 * TOS`227228.229230**`BINARY_FLOOR_DIVIDE`()**231232Реализует233234`TOS = TOS1 // TOS`235236.237238**`BINARY_TRUE_DIVIDE`()**239240Реализует241242`TOS = TOS1 / TOS`243244, когда245246`from __future__ import division`247248находится в действии.249250**`BINARY_MODULO`()**251252Реализует253254`TOS = TOS1 % TOS`255256.257258**`BINARY_ADD`()**259260Реализует261262`TOS = TOS1 + TOS`263264.265266**`BINARY_SUBTRACT`()**267268Реализует269270`TOS = TOS1 - TOS`271272.273274**`BINARY_SUBSCR`()**275276Реализует277278`TOS = TOS1[TOS]`279280.281282**`BINARY_LSHIFT`()**283284Реализует285286`TOS = TOS1 << TOS`287288.289290**`BINARY_RSHIFT`()**291292Реализует293294`TOS = TOS1 >> TOS`295296.297298**`BINARY_AND`()**299300Реализует301302`TOS = TOS1 & TOS`303304.305306**`BINARY_XOR`()**307308Реализует309310`TOS = TOS1 ^ TOS`311312.313314**`BINARY_OR`()**315316Реализует317318`TOS = TOS1 | TOS`319320.321322Операции на месте аналогичны бинарным: они также удаляют TOS и TOS1 и помещают результат обратно в стек, но операция выполняется на месте, если TOS1 это поддерживает, и результирующий TOS может (но не обязан) быть исходным TOS1.323324**`INPLACE_POWER`()**325326Реализует in-place:327328`TOS = TOS1 ** TOS`329330.331332**`INPLACE_MULTIPLY`()**333334Реализует in-place:335336`TOS = TOS1 * TOS`337338.339340**`INPLACE_FLOOR_DIVIDE`()**341342Реализует in-place:343344`TOS = TOS1 // TOS`345346.347348**`INPLACE_TRUE_DIVIDE`()**349350Реализует на месте351352`TOS = TOS1 / TOS`353354, когда355356`from __future__ import division`357358действует.359360**`INPLACE_MODULO`()**361362Реализует in-place:363364`TOS = TOS1 % TOS`365366.367368**`INPLACE_ADD`()**369370Реализует in-place:371372`TOS = TOS1 + TOS`373374.375376**`INPLACE_SUBTRACT`()**377378Реализует in-place:379380`TOS = TOS1 - TOS`381382.383384**`INPLACE_LSHIFT`()**385386Реализует in-place:387388`TOS = TOS1 << TOS`389390.391392**`INPLACE_RSHIFT`()**393394Реализует in-place:395396`TOS = TOS1 >> TOS`397398.399400**`INPLACE_AND`()**401402Реализует in-place:403404`TOS = TOS1 & TOS`405406.407408**`INPLACE_XOR`()**409410Реализует in-place:411412`TOS = TOS1 ^ TOS`413414.415416**`INPLACE_OR`()**417418Реализует in-place:419420`TOS = TOS1 | TOS`421422.423424**`STORE_SUBSCR`()**425426Реализует427428`TOS1[TOS] = TOS2`429430.431432**`DELETE_SUBSCR`()**433434Реализует435436`del TOS1[TOS]`437438.439440Разные опкоды.441442**`PRINT_EXPR`()**443444Реализует оператор выражения для интерактивного режима. TOS удаляется из стека и выводится на печать. В неинтерактивном режиме оператор выражения завершается445446`POP_STACK`447448.449450**`BREAK_LOOP`()**451452Завершает цикл при выполнении оператора453454[`break`](https://python-all.ru/3.0/reference/simple_stmts.html#break)455456.457458**`CONTINUE_LOOP`(*target*)**459460Продолжает цикл при выполнении оператора461462[`continue`](https://python-all.ru/3.0/reference/simple_stmts.html#continue)463464.465466*target*467468– это адрес перехода (должен быть инструкцией469470`FOR_ITER`471472).473474**`SET_ADD`()**475476Calls477478`set.add(TOS1, TOS)`479480. Used to implement set comprehensions.481482**`LIST_APPEND`()**483484Calls485486`list.append(TOS1, TOS)`487488. Used to implement list comprehensions.489490**`LOAD_LOCALS`()**491492Pushes a reference to the locals of the current scope on the stack. This is used in the code for a class definition: After the class body is evaluated, the locals are passed to the class definition.493494**`RETURN_VALUE`()**495496Возвращает TOS вызывающей стороне функции.497498**`YIELD_VALUE`()**499500Извлекает501502`TOS`503504и возвращает его из505506[*генератора*](https://python-all.ru/3.0/glossary.html#term-generator)507508.509510**`IMPORT_STAR`()**511512Загружает все символы, не начинающиеся с513514`'_'`515516, непосредственно из модуля TOS в локальное пространство имён. Модуль извлекается после загрузки всех имён. Этот опкод реализует517518`from module import *`519520.521522**`POP_BLOCK`()**523524Удаляет один блок из стека блоков. Для каждого фрейма существует стек блоков, обозначающий вложенные циклы, операторы try и тому подобное.525526**`POP_EXCEPT`()**527528Удаляет один блок из стека блоков. Извлечённый блок должен быть блоком обработчика исключений, который неявно создаётся при входе в обработчик except. Помимо извлечения лишних значений из стека фрейма, последние три извлечённых значения используются для восстановления состояния исключения.529530**`END_FINALLY`()**531532Завершает блок533534[`finally`](https://python-all.ru/3.0/reference/compound_stmts.html#finally)535536. Интерпретатор запоминает, нужно ли повторно возбуждать исключение или функция возвращается, и продолжает со следующим внешним блоком.537538**`LOAD_BUILD_CLASS`()**539540Помещает541542`builtins.__build_class__()`543544в стек. Позже она вызывается инструкцией545546`CALL_FUNCTION`547548для создания класса.549550**`WITH_CLEANUP`()**551552Очищает стек при выходе из блока оператора [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with). TOS – это привязанный метод [`__exit__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__exit__) менеджера контекста. Ниже TOS находятся 1–3 значения, указывающие, каким образом/почему был выполнен блок finally:553554- SECOND = `None`555- (SECOND, THIRD) = (`WHY_{RETURN,CONTINUE}`), retval556- SECOND = `WHY_*`; под ним нет retval557- (SECOND, THIRD, FOURTH) = exc\_info()558559В последнем случае вызывается `TOS(SECOND, THIRD, FOURTH)`, иначе `TOS(None, None, None)`. Кроме того, TOS удаляется из стека.560561Если стек представляет исключение, *и* вызов функции возвращает истинное значение, эта информация «зануляется» и заменяется одним значением `WHY_SILENCED`, чтобы предотвратить повторное возбуждение исключения инструкцией `END_FINALLY`. (Но нелокальные переходы все равно будут возобновлены.)562563**`STORE_LOCALS`**564565Извлекает TOS из стека и сохраняет его как566567`f_locals`568569текущего фрейма. Используется при построении класса.570571Все следующие опкоды требуют аргументов. Аргумент занимает два байта, причём старший байт идёт последним.572573**`STORE_NAME`(*namei*)**574575Реализует576577`name = TOS`578579.580581*namei*582583– это индекс584585*name*586587в атрибуте588589`co_names`590591объекта кода. Компилятор старается использовать592593`STORE_FAST`594595или596597`STORE_GLOBAL`598599, если это возможно.600601**`DELETE_NAME`(*namei*)**602603Реализует604605`del name`606607, где608609*namei*610611– это индекс в атрибуте612613`co_names`614615объекта кода.616617**`UNPACK_SEQUENCE`(*count*)**618619Распаковывает TOS в620621*count*622623отдельных значений, которые помещаются в стек справа налево.624625**`UNPACK_EX`(*counts*)**626627Реализует присваивание с целевой переменной со звёздочкой: распаковывает итерируемый объект в TOS в отдельные значения, где общее количество значений может быть меньше количества элементов в итерируемом объекте: одно из новых значений будет списком всех оставшихся элементов.628629Младший байт *counts* – это количество значений до спискового значения, а старший байт *counts* – количество значений после него. Результирующие значения помещаются в стек справа налево.630631**`DUP_TOPX`(*count*)**632633Дублирует634635*count*636637элементов, сохраняя их порядок. Из-за ограничений реализации638639*count*640641должен быть в диапазоне от 1 до 5 включительно.642643**`STORE_ATTR`(*namei*)**644645Реализует646647`TOS.name = TOS1`648649, где650651*namei*652653– это индекс имени в654655`co_names`656657.658659**`DELETE_ATTR`(*namei*)**660661Реализует662663`del TOS.name`664665, используя666667*namei*668669как индекс в670671`co_names`672673.674675**`STORE_GLOBAL`(*namei*)**676677Работает как678679`STORE_NAME`680681, но сохраняет имя как глобальное.682683**`DELETE_GLOBAL`(*namei*)**684685Работает как686687`DELETE_NAME`688689, но удаляет глобальное имя.690691**`LOAD_CONST`(*consti*)**692693Помещает694695`co_consts[consti]`696697в стек.698699**`LOAD_NAME`(*namei*)**700701Помещает значение, связанное с702703`co_names[namei]`704705, в стек.706707**`BUILD_TUPLE`(*count*)**708709Создает кортеж, беря710711*count*712713элементов из стека, и помещает полученный кортеж обратно в стек.714715**`BUILD_LIST`(*count*)**716717Работает как718719`BUILD_TUPLE`720721, но создает список.722723**`BUILD_SET`(*count*)**724725Работает как726727`BUILD_TUPLE`728729, но создает множество.730731**`BUILD_MAP`(*count*)**732733Помещает новый объект словаря в стек. Словарь предварительно настраивается на хранение734735*count*736737записей.738739**`LOAD_ATTR`(*namei*)**740741Заменяет TOS на742743`getattr(TOS, co_names[namei])`744745.746747**`COMPARE_OP`(*opname*)**748749Выполняет булеву операцию. Имя операции можно найти в750751`cmp_op[opname]`752753.754755**`IMPORT_NAME`(*namei*)**756757Импортирует модуль758759`co_names[namei]`760761. TOS и TOS1 извлекаются и предоставляют аргументы762763*fromlist*764765и766767*level*768769для770771[`__import__()`](https://python-all.ru/3.0/library/functions.html#__import__)772773. Объект модуля помещается в стек. Текущее пространство имен не затрагивается: для правильного оператора import последующая инструкция774775`STORE_FAST`776777изменяет пространство имен.778779**`IMPORT_FROM`(*namei*)**780781Загружает атрибут782783`co_names[namei]`784785из модуля, находящегося в TOS. Полученный объект помещается в стек, чтобы затем быть сохраненным инструкцией786787`STORE_FAST`788789.790791**`JUMP_FORWARD`(*delta*)**792793Увеличивает счётчик байт-кода на794795*delta*796797.798799**`JUMP_IF_TRUE`(*delta*)**800801Если TOS истинно, увеличить счётчик байткода на802803*delta*804805. TOS остаётся на стеке.806807**`JUMP_IF_FALSE`(*delta*)**808809Если TOS ложно, увеличить счётчик байткода на810811*delta*812813. TOS не изменяется.814815**`JUMP_ABSOLUTE`(*target*)**816817Устанавливает счётчик байткода в818819*target*820821.822823**`FOR_ITER`(*delta*)**824825`TOS`826827– это828829[*итератор*](https://python-all.ru/3.0/glossary.html#term-iterator)830831. Вызовите его метод832833`__next__()`834835. Если это возвращает новое значение, поместите его в стек (оставив итератор под ним). Если итератор сигнализирует, что он исчерпан,836837`TOS`838839извлекается, а счетчик байт-кода увеличивается на840841*delta*842843.844845**`LOAD_GLOBAL`(*namei*)**846847Загружает глобальную переменную с именем848849`co_names[namei]`850851в стек.852853**`SETUP_LOOP`(*delta*)**854855Помещает блок для цикла в стек блоков. Блок начинается с текущей инструкции и имеет размер856857*delta*858859байт.860861**`SETUP_EXCEPT`(*delta*)**862863Помещает блок try из конструкции try-except в стек блоков.864865*delta*866867указывает на первый блок except.868869**`SETUP_FINALLY`(*delta*)**870871Помещает блок try из конструкции try-except в стек блоков.872873*delta*874875указывает на блок finally.876877**`STORE_MAP`()**878879Сохраняет пару ключ-значение в словаре. Снимает со стека ключ и значение, оставляя словарь в стеке.880881**`LOAD_FAST`(*var\_num*)**882883Помещает ссылку на локальную переменную884885`co_varnames[var_num]`886887в стек.888889**`STORE_FAST`(*var\_num*)**890891Сохраняет TOS в локальную переменную892893`co_varnames[var_num]`894895.896897**`DELETE_FAST`(*var\_num*)**898899Удаляет локальную переменную900901`co_varnames[var_num]`902903.904905**`LOAD_CLOSURE`(*i*)**906907Помещает в стек ссылку на ячейку, содержащуюся в слоте908909*i*910911хранилища ячеек и свободных переменных. Имя переменной –912913`co_cellvars[i]`914915, если916917*i*918919меньше длины920921*co\_cellvars*922923. В противном случае –924925`co_freevars[i - len(co_cellvars)]`926927.928929**`LOAD_DEREF`(*i*)**930931Загружает ячейку, содержащуюся в слоте932933*i*934935хранилища ячеек и свободных переменных. Помещает ссылку на объект, который содержит ячейка, в стек.936937**`STORE_DEREF`(*i*)**938939Сохраняет TOS в ячейку, содержащуюся в слоте940941*i*942943хранилища ячеек и свободных переменных.944945**`SET_LINENO`(*lineno*)**946947Этот опкод устарел.948949**`RAISE_VARARGS`(*argc*)**950951Вызывает исключение.952953*argc*954955указывает количество параметров оператора raise (от 0 до 3). Обработчик увидит объект traceback как TOS2, параметр как TOS1, а исключение как TOS.956957**`CALL_FUNCTION`(*argc*)**958959Вызывает функцию. Младший байт960961*argc*962963указывает количество позиционных параметров, старший байт – количество именованных параметров. В стеке опкод сначала находит именованные параметры. Для каждого именованного аргумента значение находится поверх ключа. Под именованными параметрами в стеке располагаются позиционные параметры, причем самый правый параметр – наверху. Под параметрами находится вызываемый объект функции. Снимает со стека все аргументы функции и саму функцию, затем помещает в стек возвращаемое значение.964965**`MAKE_FUNCTION`(*argc*)**966967Помещает новый объект функции в стек. TOS – это код, связанный с функцией. Объект функции определяется как имеющий968969*argc*970971параметров по умолчанию, которые находятся под TOS.972973**`MAKE_CLOSURE`(*argc*)**974975Создаёт новый объект функции, устанавливает его слот976977*\_\_closure\_\_*978979и помещает его в стек. TOS – это код, связанный с функцией, TOS1 – кортеж содержащий ячейки для свободных переменных замыкания. Функция также имеет980981*argc*982983параметров по умолчанию, которые находятся под ячейками.984985**`BUILD_SLICE`(*argc*)**986987Помещает объект среза в стек. *argc* должен быть равен 2 или 3. Если он равен 2, помещается `slice(TOS1, TOS)`; если 3 – `slice(TOS2, TOS1, TOS)`. Подробнее см. встроенную функцию [`slice()`](https://python-all.ru/3.0/library/functions.html#slice).988989**`EXTENDED_ARG`(*ext*)**990991Является префиксом для любого опкода, аргумент которого слишком велик, чтобы поместиться в стандартные два байта.992993*ext*994995содержит два дополнительных байта, которые вместе с аргументом последующего опкода образуют четырехбайтовый аргумент, причем996997*ext*998999является двумя старшими байтами.10001001**`CALL_FUNCTION_VAR`(*argc*)**10021003Вызывает функцию.10041005*argc*10061007интерпретируется так же, как в10081009`CALL_FUNCTION`10101011. Верхний элемент стека содержит список аргументов переменной длины, за которым следуют именованные и позиционные аргументы.10121013**`CALL_FUNCTION_KW`(*argc*)**10141015Вызывает функцию.10161017*argc*10181019интерпретируется так же, как в10201021`CALL_FUNCTION`10221023. Верхний элемент в стеке содержит словарь именованных аргументов, за которым следуют явные именованные и позиционные аргументы.10241025**`CALL_FUNCTION_VAR_KW`(*argc*)**10261027Вызывает функцию.10281029*argc*10301031интерпретируется так же, как в10321033`CALL_FUNCTION`10341035. Верхний элемент в стеке содержит словарь именованных аргументов, за которым следуют кортеж переменных аргументов, а затем явные именованные и позиционные аргументы.10361037**`HAVE_ARGUMENT`()**10381039Это не совсем опкод. Он обозначает разделительную линию между опкодами, не принимающими аргументы10401041`< HAVE_ARGUMENT`10421043, и теми, которые принимают10441045`>= HAVE_ARGUMENT`10461047.1048