Как читать байт-код python?
мне очень сложно понять байт-код Python и его dis
модуль.
import dis
def func():
x = 1
dis.dis(func)
приведенный выше код при вводе интерпретатора выдает следующий вывод:
0 LOAD_CONST 1(1)
3 STORE_FAST 0(x)
6 LOAD_CONST 0(NONE)
9 RETURN_VALUE
например:
что означает LOAD_CONST
, STORE_FAST
а цифры, как 0
, 3
, 6
и 9
?
конкретный ресурс, где я могу найти эту информацию будет высоко ценится.
1 ответов
числа перед байт-кодами смещаются в исходные двоичные байт-коды:
>>> func.__code__.co_code
'd\x01\x00}\x00\x00d\x00\x00S'
некоторые байт-коды поставляются с дополнительной информацией (аргументами), которые влияют на то, как работает каждый байт-код, смещение говорит вам, в какой позиции в байт-потоке был найден байт-код.
на LOAD_CONST
байт-код (ASCII d
, hex 64) сопровождается двумя дополнительными байтами, кодирующими ссылку на константу, связанную с байт-кодом, например. В результате STORE_FAST
код операции (ASCII }
, hex 7D) находится в индексе 3.
на dis
документацию списки что означает каждая инструкция. Для LOAD_CONST
Он говорит:
запихивает
co_consts[consti]
в стек.
что относится к co_consts
структура, которая всегда присутствует с объектом кода; компилятор создает это:
>>> func.__code__.co_consts
(None, 1)
код операции загружает индекс 1 из этой структуры (01 00 байт в байт-код кодирует a 1), и dis
посмотрел это для вас; это значение 1
.
следующая инструкция,STORE_FAST
описано так:
магазины TOS в местном
co_varnames[var_num]
.
здесь ТОС относится к верхней части стека; обратите внимание, что LOAD_CONST
просто толкнул что-то на стеке,1
значение. co_varnames
другая структура; она ссылается на имена локальных переменных, индекс ссылок на код операции 0:
>>> func.__code__.co_varnames
('x',)
dis
тоже посмотрел, и имя, которое вы использовали в своем коде, -x
. Таким образом, этот код операции хранится 1
на x
.
еще один LOAD_CONST
нагрузки None
в стек из индекса 0, за которым следует RETURN_VALUE
:
возвращает с TOS вызывающему объекту функции.
таким образом, эта инструкция занимает верхнюю часть стека (с None
Constant) и возвращается из этого блока кода. None
является возвращаемым значением по умолчанию для функций без явного return
заявление.
вы что-то пропустили из dis
выход, номера строк:
>>> dis.dis(func)
2 0 LOAD_CONST 1 (1)
3 STORE_FAST 0 (x)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
Примечание 2
в первой строке; это номер строки в исходном источнике, который содержит код Python, который использовался для этих инструкций. Объекты Python кода co_lnotab
и co_firstlineno
атрибуты, которые позволяют сопоставлять байт-коды с номерами строк в исходном источнике. dis
делает это для вас при отображении разборки.