opcode在 3.7 之前的版本中没有等效的跟踪。如果有,该功能一开始就不会添加到 3.7 中。
如果您可以升级到 3.7,那么您想要的很简单:
def tracefunc(frame, event, arg):
if event == 'call':
frame.f_trace_opcodes = True
elif event == 'opcode':
if frame.f_code.co_code[frame.f_lasti] == dis.opmap['MAKE_FUNCTION']:
makefunctiontracefunc(frame)
return tracefunc
sys.settrace(tracefunc)
Run Code Online (Sandbox Code Playgroud)
但是如果你不能……你可以做一些更复杂的事情,这取决于你想要这个的原因,但没有一个是远程容易的:
line跟踪,并检查代码直到下一行。这对于def来说是微不足道的,但是对于lambda(和理解1)这将是一个很大的痛苦,因为一个lambda(甚至五个)可以出现在语句的中间。您可以ast.parse查看源代码或检查字节码,以找出其中定义了函数,但仍然无法在定义时立即调用您的钩子。NodeTransformer注入对某个函数2 的调用,然后编译转换后的树。但是您也可以在字节码级别使用或,在每个 之前或之后执行此操作。3deflambdabytecodebyteplayMAKE_FUNCTIONpdb而不是编写自己的调试器。我不确定这是否会有所帮助,因为首先pdb无法遍历表达式的一部分。MAKE_FUNCTION在ceval调用代码的循环中的处理程序中添加断点。当然,你的代码是在调试器的解释,这可能是对的Pythongdb和lldb,但它仍然是不一样的Python解释器,你正在调试。而且,虽然可以递归地将代码评估到已调试的解释器中(或触发它的pdb),但这并不容易,而且您在处理它时到处都是段错误。1.推导式(除了列表推导式,在2.x中)是通过定义然后调用一个函数来实现的。因此,任何依赖于MAKE_FUNCTION操作码或类似方法的方法也会触发推导式,而那些依赖于源代码或 AST 解析的方法则不会(当然,除非您明确这样做)。
2. 显然,您还需要import在每个模块的顶部注入一个以使该功能可用,或者将该功能注入内置模块。
3. 并且MAKE_CLOSURE,对于早期版本的 Python。
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |