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

dis.md

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

1> **Источник:** https://python-all.ru/3.1/library/dis.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 30.12. `dis` – Дисассемблер байт-кода Python89Модуль `dis` поддерживает анализ CPython [*байт-кода*](https://python-all.ru/3.1/glossary.html#term-bytecode) путём его дизассемблирования. CPython байт-код, который этот модуль принимает на вход, определён в файле `Include/opcode.h` и используется компилятором и интерпретатором.1011**Особенность реализации CPython:** Байт-код – деталь реализации интерпретатора CPython! Не гарантируется, что байт-код не будет добавлен, удалён или изменён в разных версиях Python. Не следует рассчитывать, что этот модуль будет работать в других виртуальных машинах Python или в других выпусках Python.1213Пример: дана функция `myfunc()`:1415```python16def myfunc(alist):17    return len(alist)18```1920Для получения дизассемблированного кода `myfunc()` можно использовать следующую команду:2122```python23>>> dis.dis(myfunc)24  2           0 LOAD_GLOBAL              0 (len)25              3 LOAD_FAST                0 (alist)26              6 CALL_FUNCTION            127              9 RETURN_VALUE28```2930(«2» – это номер строки).3132Модуль `dis` определяет следующие функции и константы:3334#### `dis.dis(x=None)`3536Дизассемблирует объект3738*x*3940.4142*x*4344может обозначать модуль, класс, метод, функцию, объект кода, строку исходного кода или последовательность байтов сырого байт-кода. Для модуля дизассемблируются все функции. Для класса – все методы. Для объекта кода или последовательности сырого байт-кода выводится по одной строке на каждую инструкцию байт-кода. Строки сначала компилируются в объекты кода с помощью встроенной функции4546[`compile()`](https://python-all.ru/3.1/library/functions.html#compile)4748, а затем дизассемблируются. Если объект не указан, функция дизассемблирует последнюю трассировку.4950#### `dis.distb(tb=None)`5152Дисассемблирует функцию, находящуюся на вершине стека traceback; если traceback не передан, используется последний. Указывается инструкция, вызвавшая исключение.5354#### `dis.disassemble(code, lasti=-1)`5556#### `dis.disco(code, lasti=-1)`5758Дисассемблирует объект кода, указывая последнюю инструкцию, если передан *lasti*. Результат разбит на следующие столбцы:59601. номер строки для первой инструкции каждой строки612. текущая инструкция, помечена как `-->`,623. инструкция с меткой, помечена `>>`,634. адрес инструкции,645. название кода операции,656. параметры операции и667. интерпретация параметров в скобках.6768Интерпретация параметров распознаёт имена локальных и глобальных переменных, константные значения, цели переходов и операторы сравнения.6970#### `dis.findlinestarts(code)`7172Эта функция-генератор использует атрибуты7374`co_firstlineno`7576и7778`co_lnotab`7980объекта кода8182*code*8384для поиска смещений, соответствующих началам строк в исходном коде. Они генерируются в виде пар8586`(offset, lineno)`8788.8990#### `dis.findlabels(code)`9192Определяет все смещения в объекте кода9394*code*9596, которые являются целями перехода, и\\nвозвращает список этих смещений.9798#### `dis.opname`99100Последовательность имён операций, индексируемая с помощью байткода.101102#### `dis.opmap`103104Словарь, сопоставляющий имена операций с байткодами.105106#### `dis.cmp_op`107108Последовательность всех имён операций сравнения.109110#### `dis.hasconst`111112Последовательность байткодов, имеющих постоянный параметр.113114#### `dis.hasfree`115116Последовательность байткодов, обращающихся к свободной переменной.117118#### `dis.hasname`119120Последовательность байткодов, обращающихся к атрибуту по имени.121122#### `dis.hasjrel`123124Последовательность байткодов, имеющих относительную цель перехода.125126#### `dis.hasjabs`127128Последовательность байткодов, имеющих абсолютную цель перехода.129130#### `dis.haslocal`131132Последовательность байткодов, обращающихся к локальной переменной.133134#### `dis.hascompare`135136Последовательность байткодов логических операций.137138## 30.12.1. Инструкции байткода Python139140В настоящее время компилятор Python генерирует следующие инструкции байткода.141142**Общие инструкции**143144**`STOP_CODE`**145146Указывает компилятору на конец кода, не используется интерпретатором.147148**`NOP`**149150Код, который ничего не делает. Используется в качестве заполнителя оптимизатором байт-кода.151152**`POP_TOP`**153154Удаляет элемент с вершины стека (TOS).155156**`ROT_TWO`**157158Меняет местами два верхних элемента стека.159160**`ROT_THREE`**161162Поднимает второй и третий элементы стека на одну позицию вверх, перемещает верхний вниз на третью позицию.163164**`ROT_FOUR`**165166Поднимает второй, третий и четвёртый элементы стека на одну позицию вверх, перемещает верхний элемент вниз на четвёртую позицию.167168**`DUP_TOP`**169170Дублирует ссылку на вершине стека.171172**Унарные операции**173174Унарные операции берут элемент с вершины стека, применяют операцию и помещают результат обратно на стек.175176**`UNARY_POSITIVE`**177178Реализует179180`TOS = +TOS`181182.183184**`UNARY_NEGATIVE`**185186Реализует187188`TOS = -TOS`189190.191192**`UNARY_NOT`**193194Реализует195196`TOS = не TOS`197198.199200**`UNARY_INVERT`**201202Реализует203204`TOS = ~TOS`205206.207208**`GET_ITER`**209210Реализует211212`TOS = iter(TOS)`213214.215216**Бинарные операции**217218Бинарные операции удаляют из стека элемент с вершины (TOS) и второй сверху элемент стека (TOS1). Они выполняют операцию и помещают результат обратно в стек.219220**`BINARY_POWER`**221222Реализует223224`TOS = TOS1 ** TOS`225226.227228**`BINARY_MULTIPLY`**229230Реализует231232`TOS = TOS1 * TOS`233234.235236**`BINARY_FLOOR_DIVIDE`**237238Реализует239240`TOS = TOS1 // TOS`241242.243244**`BINARY_TRUE_DIVIDE`**245246Реализует247248`TOS = TOS1 / TOS`249250.251252**`BINARY_MODULO`**253254Реализует255256`TOS = TOS1 % TOS`257258.259260**`BINARY_ADD`**261262Реализует263264`TOS = TOS1 + TOS`265266.267268**`BINARY_SUBTRACT`**269270Реализует271272`TOS = TOS1 - TOS`273274.275276**`BINARY_SUBSCR`**277278Реализует279280`TOS = TOS1[TOS]`281282.283284**`BINARY_LSHIFT`**285286Реализует287288`TOS = TOS1 << TOS`289290.291292**`BINARY_RSHIFT`**293294Реализует295296`TOS = TOS1 >> TOS`297298.299300**`BINARY_AND`**301302Реализует303304`TOS = TOS1 & TOS`305306.307308**`BINARY_XOR`**309310Реализует311312`TOS = TOS1 ^ TOS`313314.315316**`BINARY_OR`**317318Реализует319320`TOS = TOS1 | TOS`321322.323324**Операции на месте**325326Операции на месте аналогичны бинарным: они также удаляют TOS и TOS1 и помещают результат обратно в стек, но операция выполняется на месте, если TOS1 это поддерживает, и результирующий TOS может (но не обязан) быть исходным TOS1.327328**`INPLACE_POWER`**329330Реализует in-place:331332`TOS = TOS1 ** TOS`333334.335336**`INPLACE_MULTIPLY`**337338Реализует in-place:339340`TOS = TOS1 * TOS`341342.343344**`INPLACE_FLOOR_DIVIDE`**345346Реализует in-place:347348`TOS = TOS1 // TOS`349350.351352**`INPLACE_TRUE_DIVIDE`**353354Реализует in-place:355356`TOS = TOS1 / TOS`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.1/reference/simple_stmts.html#break)455456.457458**`CONTINUE_LOOP`(*target*)**459460Продолжает цикл при выполнении оператора461462[`continue`](https://python-all.ru/3.1/reference/simple_stmts.html#continue)463464.465466*target*467468– это адрес перехода (должен быть инструкцией469470`FOR_ITER`471472).473474**`SET_ADD`(*i*)**475476Вызывает477478`set.add(TOS1[-i], TOS)`479480. Используется для реализации множественных включений (set comprehensions).481482**`LIST_APPEND`(*i*)**483484Вызывает485486`list.append(TOS[-i], TOS)`487488. Используется для реализации списковых включений (list comprehensions).489490**`MAP_ADD`(*i*)**491492Вызывает493494`dict.setitem(TOS1[-i], TOS, TOS1)`495496. Используется для реализации словарных включений (dict comprehensions).497498Для всех инструкций SET\_ADD, LIST\_APPEND и MAP\_ADD, после извлечения добавляемого значения или пары ключ/значение, объект-контейнер остаётся в стеке, чтобы его можно было использовать в следующих итерациях цикла.499500**`RETURN_VALUE`**501502Возвращает TOS вызывающей стороне функции.503504**`YIELD_VALUE`**505506Извлекает507508`TOS`509510и возвращает его из511512[*генератора*](https://python-all.ru/3.1/glossary.html#term-generator)513514.515516**`IMPORT_STAR`**517518Загружает все символы, не начинающиеся с519520`'_'`521522, непосредственно из модуля TOS в локальное пространство имён. Модуль извлекается после загрузки всех имён. Этот опкод реализует523524`from module import *`525526.527528**`POP_BLOCK`**529530Удаляет один блок из стека блоков. Для каждого фрейма существует стек блоков, обозначающий вложенные циклы, операторы try и тому подобное.531532**`POP_EXCEPT`**533534Удаляет один блок из стека блоков. Извлечённый блок должен быть блоком обработчика исключений, который неявно создаётся при входе в обработчик except. Помимо извлечения лишних значений из стека фрейма, последние три извлечённых значения используются для восстановления состояния исключения.535536**`END_FINALLY`**537538Завершает блок539540[`finally`](https://python-all.ru/3.1/reference/compound_stmts.html#finally)541542. Интерпретатор запоминает, нужно ли повторно возбуждать исключение или функция возвращается, и продолжает со следующим внешним блоком.543544**`LOAD_BUILD_CLASS`**545546Помещает547548`builtins.__build_class__()`549550в стек. Позже она вызывается инструкцией551552`CALL_FUNCTION`553554для создания класса.555556**`WITH_CLEANUP`**557558Очищает стек при выходе из блока оператора [`with`](https://python-all.ru/3.1/reference/compound_stmts.html#with). TOS – это привязанный метод [`__exit__()`](https://python-all.ru/3.1/reference/datamodel.html#object.__exit__) менеджера контекста. Ниже TOS находятся 1–3 значения, указывающие, каким образом/почему был выполнен блок finally:559560- SECOND = `None`561- (SECOND, THIRD) = (`WHY_{RETURN,CONTINUE}`), retval562- SECOND = `WHY_*`; под ним нет retval563- (SECOND, THIRD, FOURTH) = exc\_info()564565В последнем случае вызывается `TOS(SECOND, THIRD, FOURTH)`, иначе `TOS(None, None, None)`. Кроме того, TOS удаляется из стека.566567Если стек представляет исключение, *и* вызов функции возвращает истинное значение, эта информация «зануляется» и заменяется одним значением `WHY_SILENCED`, чтобы предотвратить повторное возбуждение исключения инструкцией `END_FINALLY`. (Но нелокальные переходы все равно будут возобновлены.)568569**`STORE_LOCALS`**570571Извлекает TOS из стека и сохраняет его как572573`f_locals`574575текущего фрейма. Используется при построении класса.576577Все следующие опкоды требуют аргументов. Аргумент занимает два байта, причём старший байт идёт последним.578579**`STORE_NAME`(*namei*)**580581Реализует582583`name = TOS`584585.586587*namei*588589– это индекс590591*name*592593в атрибуте594595`co_names`596597объекта кода. Компилятор старается использовать598599`STORE_FAST`600601или602603`STORE_GLOBAL`604605, если это возможно.606607**`DELETE_NAME`(*namei*)**608609Реализует610611`del name`612613, где614615*namei*616617– это индекс в атрибуте618619`co_names`620621объекта кода.622623**`UNPACK_SEQUENCE`(*count*)**624625Распаковывает TOS в626627*count*628629отдельных значений, которые помещаются в стек справа налево.630631**`UNPACK_EX`(*counts*)**632633Реализует присваивание с целевой переменной со звёздочкой: распаковывает итерируемый объект в TOS в отдельные значения, где общее количество значений может быть меньше количества элементов в итерируемом объекте: одно из новых значений будет списком всех оставшихся элементов.634635Младший байт *counts* – это количество значений до спискового значения, а старший байт *counts* – количество значений после него. Результирующие значения помещаются в стек справа налево.636637**`DUP_TOPX`(*count*)**638639Дублирует640641*count*642643элементов, сохраняя их порядок. Из-за ограничений реализации644645*count*646647должен быть в диапазоне от 1 до 5 включительно.648649**`STORE_ATTR`(*namei*)**650651Реализует652653`TOS.name = TOS1`654655, где656657*namei*658659– это индекс имени в660661`co_names`662663.664665**`DELETE_ATTR`(*namei*)**666667Реализует668669`del TOS.name`670671, используя672673*namei*674675как индекс в676677`co_names`678679.680681**`STORE_GLOBAL`(*namei*)**682683Работает как684685`STORE_NAME`686687, но сохраняет имя как глобальное.688689**`DELETE_GLOBAL`(*namei*)**690691Работает как692693`DELETE_NAME`694695, но удаляет глобальное имя.696697**`LOAD_CONST`(*consti*)**698699Помещает700701`co_consts[consti]`702703в стек.704705**`LOAD_NAME`(*namei*)**706707Помещает значение, связанное с708709`co_names[namei]`710711, в стек.712713**`BUILD_TUPLE`(*count*)**714715Создает кортеж, беря716717*count*718719элементов из стека, и помещает полученный кортеж обратно в стек.720721**`BUILD_LIST`(*count*)**722723Работает как724725`BUILD_TUPLE`726727, но создает список.728729**`BUILD_SET`(*count*)**730731Работает как732733`BUILD_TUPLE`734735, но создает множество.736737**`BUILD_MAP`(*count*)**738739Помещает новый объект словаря в стек. Словарь предварительно настраивается на хранение740741*count*742743записей.744745**`LOAD_ATTR`(*namei*)**746747Заменяет TOS на748749`getattr(TOS, co_names[namei])`750751.752753**`COMPARE_OP`(*opname*)**754755Выполняет булеву операцию. Имя операции можно найти в756757`cmp_op[opname]`758759.760761**`IMPORT_NAME`(*namei*)**762763Импортирует модуль764765`co_names[namei]`766767. TOS и TOS1 извлекаются и предоставляют аргументы768769*fromlist*770771и772773*level*774775для776777[`__import__()`](https://python-all.ru/3.1/library/functions.html#__import__)778779. Объект модуля помещается в стек. Текущее пространство имен не затрагивается: для правильного оператора import последующая инструкция780781`STORE_FAST`782783изменяет пространство имен.784785**`IMPORT_FROM`(*namei*)**786787Загружает атрибут788789`co_names[namei]`790791из модуля, находящегося в TOS. Полученный объект помещается в стек, чтобы затем быть сохраненным инструкцией792793`STORE_FAST`794795.796797**`JUMP_FORWARD`(*delta*)**798799Увеличивает счётчик байт-кода на800801*delta*802803.804805**`POP_JUMP_IF_TRUE`(*target*)**806807Если TOS истинно, устанавливает счётчик байткода в808809*target*810811. TOS извлекается из стека.812813**`POP_JUMP_IF_FALSE`(*target*)**814815Если TOS ложно, устанавливает счётчик байткода в816817*target*818819. TOS извлекается из стека.820821**`JUMP_IF_TRUE_OR_POP`(*target*)**822823Если TOS истинно, устанавливает счетчик байткода в824825*target*826827и оставляет TOS в стеке. В противном случае (TOS ложно) TOS извлекается.828829**`JUMP_IF_FALSE_OR_POP`(*target*)**830831Если TOS ложен, устанавливает счетчик байт-кода в832833*target*834835и оставляет TOS на стеке. В противном случае (TOS истинен) TOS снимается со стека.836837**`JUMP_ABSOLUTE`(*target*)**838839Устанавливает счётчик байткода в840841*target*842843.844845**`FOR_ITER`(*delta*)**846847`TOS`848849– это850851[*итератор*](https://python-all.ru/3.1/glossary.html#term-iterator)852853. Вызовите его метод854855`__next__()`856857. Если это возвращает новое значение, поместите его в стек (оставив итератор под ним). Если итератор сигнализирует, что он исчерпан,858859`TOS`860861извлекается, а счетчик байт-кода увеличивается на862863*delta*864865.866867**`LOAD_GLOBAL`(*namei*)**868869Загружает глобальную переменную с именем870871`co_names[namei]`872873в стек.874875**`SETUP_LOOP`(*delta*)**876877Помещает блок для цикла в стек блоков. Блок начинается с текущей инструкции и имеет размер878879*delta*880881байт.882883**`SETUP_EXCEPT`(*delta*)**884885Помещает блок try из конструкции try-except в стек блоков.886887*delta*888889указывает на первый блок except.890891**`SETUP_FINALLY`(*delta*)**892893Помещает блок try из конструкции try-except в стек блоков.894895*delta*896897указывает на блок finally.898899**`STORE_MAP`**900901Сохраняет пару ключ-значение в словаре. Снимает со стека ключ и значение, оставляя словарь в стеке.902903**`LOAD_FAST`(*var\_num*)**904905Помещает ссылку на локальную переменную906907`co_varnames[var_num]`908909в стек.910911**`STORE_FAST`(*var\_num*)**912913Сохраняет TOS в локальную переменную914915`co_varnames[var_num]`916917.918919**`DELETE_FAST`(*var\_num*)**920921Удаляет локальную переменную922923`co_varnames[var_num]`924925.926927**`LOAD_CLOSURE`(*i*)**928929Помещает в стек ссылку на ячейку, содержащуюся в слоте930931*i*932933хранилища ячеек и свободных переменных. Имя переменной –934935`co_cellvars[i]`936937, если938939*i*940941меньше длины942943*co\_cellvars*944945. В противном случае –946947`co_freevars[i - len(co_cellvars)]`948949.950951**`LOAD_DEREF`(*i*)**952953Загружает ячейку, содержащуюся в слоте954955*i*956957хранилища ячеек и свободных переменных. Помещает ссылку на объект, который содержит ячейка, в стек.958959**`STORE_DEREF`(*i*)**960961Сохраняет TOS в ячейку, содержащуюся в слоте962963*i*964965хранилища ячеек и свободных переменных.966967**`RAISE_VARARGS`(*argc*)**968969Вызывает исключение.970971*argc*972973указывает количество параметров оператора raise (от 0 до 3). Обработчик увидит объект traceback как TOS2, параметр как TOS1, а исключение как TOS.974975**`CALL_FUNCTION`(*argc*)**976977Вызывает функцию. Младший байт978979*argc*980981указывает количество позиционных параметров, старший байт – количество именованных параметров. В стеке опкод сначала находит именованные параметры. Для каждого именованного аргумента значение находится поверх ключа. Под именованными параметрами в стеке располагаются позиционные параметры, причем самый правый параметр – наверху. Под параметрами находится вызываемый объект функции. Снимает со стека все аргументы функции и саму функцию, затем помещает в стек возвращаемое значение.982983**`MAKE_FUNCTION`(*argc*)**984985Помещает новый объект функции в стек. TOS – это код, связанный с функцией. Объект функции определяется как имеющий986987*argc*988989параметров по умолчанию, которые находятся под TOS.990991**`MAKE_CLOSURE`(*argc*)**992993Создаёт новый объект функции, устанавливает его слот994995*\_\_closure\_\_*996997и помещает его в стек. TOS – это код, связанный с функцией, TOS1 – кортеж содержащий ячейки для свободных переменных замыкания. Функция также имеет998999*argc*10001001параметров по умолчанию, которые находятся под ячейками.10021003**`BUILD_SLICE`(*argc*)**10041005Помещает объект среза в стек. *argc* должен быть равен 2 или 3. Если он равен 2, помещается `slice(TOS1, TOS)`; если 3 – `slice(TOS2, TOS1, TOS)`. Подробнее см. встроенную функцию [`slice()`](https://python-all.ru/3.1/library/functions.html#slice).10061007**`EXTENDED_ARG`(*ext*)**10081009Является префиксом для любого опкода, аргумент которого слишком велик, чтобы поместиться в стандартные два байта.10101011*ext*10121013содержит два дополнительных байта, которые вместе с аргументом последующего опкода образуют четырехбайтовый аргумент, причем10141015*ext*10161017является двумя старшими байтами.10181019**`CALL_FUNCTION_VAR`(*argc*)**10201021Вызывает функцию.10221023*argc*10241025интерпретируется так же, как в10261027`CALL_FUNCTION`10281029. Верхний элемент стека содержит список аргументов переменной длины, за которым следуют именованные и позиционные аргументы.10301031**`CALL_FUNCTION_KW`(*argc*)**10321033Вызывает функцию.10341035*argc*10361037интерпретируется так же, как в10381039`CALL_FUNCTION`10401041. Верхний элемент в стеке содержит словарь именованных аргументов, за которым следуют явные именованные и позиционные аргументы.10421043**`CALL_FUNCTION_VAR_KW`(*argc*)**10441045Вызывает функцию.10461047*argc*10481049интерпретируется так же, как в10501051`CALL_FUNCTION`10521053. Верхний элемент в стеке содержит словарь именованных аргументов, за которым следуют кортеж переменных аргументов, а затем явные именованные и позиционные аргументы.10541055**`HAVE_ARGUMENT`**10561057Это не совсем опкод. Он обозначает разделительную линию между опкодами, не принимающими аргументы10581059`< HAVE_ARGUMENT`10601061, и теми, которые принимают10621063`>= HAVE_ARGUMENT`10641065.1066