2024-06-24 12:33:56 发布
网友
有没有办法钩住CPython解释器,以便每次函数创建(def,lambda)都会导致对我定义的过程的调用?^不幸的是,{}和sys.setprofile似乎不能同时涵盖def和lambda。你知道吗
def
lambda
sys.setprofile
Python3.7似乎有f_trace_opcodes。。。早期版本有什么选择吗?你知道吗
f_trace_opcodes
在3.7之前的版本中没有与opcode跟踪等价的东西。如果有的话,这个特性本来就不会添加到3.7中。你知道吗
opcode
如果您可以升级到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)
但是如果你不能…你可以做很多更复杂的事情,这取决于你想要这个的理由,但是没有一件是简单的:
line
ast.parse
MAKE_FUNCTION
pdb
ceval
gdb
lldb
1。理解(2.x中的列表理解除外)是通过定义然后调用函数来实现的。因此,任何依赖于MAKE_FUNCTION操作码或类似操作码的方法也会触发理解,而那些依赖于源代码或AST解析的方法则不会(当然,除非您显式地这样做)。
2。显然,您还需要在每个模块的顶部插入一个import,以使该函数可用,或者将该函数插入到内置模块中。
import
3。和MAKE_CLOSURE,用于早期版本的Python。
MAKE_CLOSURE
在3.7之前的版本中没有与
opcode
跟踪等价的东西。如果有的话,这个特性本来就不会添加到3.7中。你知道吗如果您可以升级到3.7,那么您想要的很简单:
但是如果你不能…你可以做很多更复杂的事情,这取决于你想要这个的理由,但是没有一件是简单的:
line
跟踪,检查代码直到下一行。这对于def
来说是微不足道的,但是对于lambda
(和理解1)来说,这将是一个巨大的痛苦,因为一个lambda
(甚至其中五个)可能出现在语句的中间。您可以ast.parse
源代码,或者检查字节码,以确定其中定义了函数,但是在定义时仍然无法正确调用钩子。你知道吗def
和lambda
节点之前或之后注入对函数2的调用,然后编译转换后的树。但是你也可以在字节码级别用^{MAKE_FUNCTION
之前或之后pdb
,而不是编写自己的调试器。我不确定这是否有帮助,因为pdb
根本没有办法遍历表达式的一部分。你知道吗ceval
循环的MAKE_FUNCTION
处理程序中添加断点。当然,您的代码在调试器的解释器中,它可以是gdb
和lldb
的Python解释器,但它仍然不是您正在调试的Python解释器。而且,虽然可以递归地将代码求值到已调试的解释器中(或者触发它的pdb
),但这并不容易,而且您在计算代码时会到处都是错误。你知道吗1。理解(2.x中的列表理解除外)是通过定义然后调用函数来实现的。因此,任何依赖于
MAKE_FUNCTION
操作码或类似操作码的方法也会触发理解,而那些依赖于源代码或AST解析的方法则不会(当然,除非您显式地这样做)。2。显然,您还需要在每个模块的顶部插入一个
import
,以使该函数可用,或者将该函数插入到内置模块中。3。和
MAKE_CLOSURE
,用于早期版本的Python。相关问题 更多 >
编程相关推荐