Я играл с dis, чтобы лучше понять PVM, и написал функцию ниже: -
def analyzeThis(co):
# loops through code objects and prints relevant info for analysis
if not hasattr(co, 'co_code'):
raise TypeError("Arg should be code object. Type is:",str(co))
# create a code objects list to support recursively analyzing functions
code_objects = [co]
while len(code_objects)>0:
# pop first code object from list
c = code_objects.pop(0)
# print header info for first code object
print("\n------------------")
print(dis.code_info(c))
# get bytecodes & set eval stack count to zero
bc = dis.Bytecode(c)
eval_stack_count = 0
# set up string formatting and table headers
f_string ="{0:3} {1:2} {2:3} {3:4} {4:<18} {5:3} {6:>3} {7:>12} "
print("\n",f_string.format("le","JT","off","code","name","sco", "arg", "argval" ))
# loop through all the code instructions with special handling for any code objects found
# eg if starting at a Class level functions contained within
for ins in bc:
if isinstance(ins.argval, types.CodeType):
code_objects.append(ins.argval)
argval = str(ins.argval)[:str(ins.argval).index(",")]
else:
argval = ins.argval
eval_stack_count += dis.stack_effect(ins.opcode,ins.arg)
print(f_string.
format(ins.starts_line if ins.starts_line is not None else "",
">>" if ins.is_jump_target else "",
ins.offset,
ins.opcode,
ins.opname,
eval_stack_count,
ins.arg if ins.arg is not None else "",
argval if argval is not None else "")
)
Вывод аналогичен dis.dis (): -
Я хотел бы получить и распечатать строку исходного кода, а не только начальный номер строки, чтобы мне было легче сравнивать исходный код и инструкции. Как я мог это сделать?