Перекомпилировать инструкции байт-кода Python

Предположим, у меня есть speak функция:

def speak():
    print("moo")

Я могу разобрать его, как обычно, с dis.dis:

>>> dis.dis(speak)
  2           0 LOAD_GLOBAL              0 (print)
              3 LOAD_CONST               1 ('moo')
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
              9 POP_TOP
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE

Но я хочу уничтожить объект кода, связанный с speak функция в последовательность инструкций, а затем скомпилировать их обратно. С помощью dis.Bytecode Я могу получить последовательность dis.Instruction s, который представляет объект кода:

>>> bytecode = dis.Bytecode(speak)
>>> for instruction in bytecode:
...     print(instruction)
... 
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=0, starts_line=2, is_jump_target=False)
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval='moo', argrepr="'moo'", offset=3, starts_line=None, is_jump_target=False)
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=6, starts_line=None, is_jump_target=False)
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=9, starts_line=None, is_jump_target=False)
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=10, starts_line=None, is_jump_target=False)
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=13, starts_line=None, is_jump_target=False)

Есть ли простой способ собрать эти Instruction объекты в исходный код объекта?

Например, я ищу compile_back функция, которая будет принимать последовательность инструкций и выводить exec Utable код объекта:

>>> code_object = compile_back(dis.get_instructions(speak))
>>> exec(code_object)
moo

1 ответ

Последовательность Instruction объекты из dis.Bytecode недостаточно для восстановления объекта кода. Кодовый объект - это не просто последовательность инструкций; он включает в себя множество других данных, таких как количество аргументов, размер стека оценки, флаги, указывающие различные свойства и т. д. Большинство этих вещей (кратко) описаны в таблице в inspect модульные документы, но есть даже какое-то "пустое место", недоступное обычным способом.

Instruction Объектов было бы достаточно, чтобы восстановить большую часть информации объекта кода, но не всю. С некоторыми опасными допущениями вы могли бы получить что-то, что обычно работает, но было бы лучше сначала сохранить больше информации из исходного объекта кода.

В любом случае, прямого пути нет.

Другие вопросы по тегам