所以我正在玩 sys.settrace
功能。在 Python 3.7 中,添加了新的 opcode
事件
'opcode'
The interpreter is about to execute a new opcode (see dis for opcode details). The local trace function is called; arg is None; the return value specifies the new local trace function. Per-opcode events are not emitted by default: they must be explicitly requested by settingf_trace_opcodes
to True on the frame.
我能够获取那些操作码事件,但是似乎没有更多信息——我什至不知道操作码是什么以及它在做什么。
此事件是否仅带来更精细的粒度,而没有提供任何额外信息?
最佳答案
如果您想了解更多信息,则需要检查传递到跟踪函数的 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()
关于python - 在 Python 3.7 中,sys.settrace 中的 'opcode' 事件是否提供有关字节码本身的任何信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51349074/