如果您想了解更多信息,则需要检查frame传递给跟踪函数的参数。特别是,您希望查看frame.f_lasti执行的最后一条指令并frame.f_code.co_code访问该指令。将这两者一起使用将为您提供实际的操作码。如果你想要助记符,那么你会想要使用dis.opname; 但是,如果您只是将它与另一个操作码匹配,那么您可以dis.opmap改用它。以下示例是人为设计的,但它演示了使用刚刚提供的提示可以实现的一些功能:
#! /usr/bin/env python3
import dis
import sys
def main():
dis.dis(add)
sys.settrace(get_trace(False, get_callback(celebrate)))
total = add(1, 2)
print(f'total = {total}')
sys.settrace(None)
total = add(3, 4)
print(f'total = {total}')
print('Done')
def get_trace(trace_lines=True, opcode_callback=None):
trace_opcodes = callable(opcode_callback)
# noinspection PyUnusedLocal
def trace(frame, event, arg):
frame.f_trace_lines = trace_lines
frame.f_trace_opcodes = trace_opcodes
if trace_opcodes and event == 'opcode':
opcode = frame.f_code.co_code[frame.f_lasti]
opname = dis.opname[opcode]
opcode_callback(frame, opcode, opname)
return trace
return trace
def get_callback(return_handler=None):
handle_return = callable(return_handler)
def echo_opcode(frame, opcode, opname):
print(f'# {opname} ({opcode}) #')
if handle_return and opcode == dis.opmap['RETURN_VALUE']:
return_handler(frame)
return echo_opcode
# noinspection PyUnusedLocal
def celebrate(frame):
print('/-------------------\\')
print('| We are returning! |')
print('\\-------------------/')
def add(a, b):
return a + b
if __name__ == '__main__':
main()