python转cpython_有什么方法可以在CPython中创建函数时执行...

在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)

但是,如果您不能…有很多更复杂的事情可以做,这取决于您想要这样做的原因,但是它们都不是一件容易的事:

>使用行跟踪,并检查代码,直到下一行.对于def来说,这是微不足道的,但是对于lambda(和理解力1)来说,这将是一个很大的痛苦,因为lambda(甚至其中的五个)可能会出现在语句的中间.您可以ast.parse源,或检查字节码,以发现其中定义了函数,但是在定义时仍然无法正确调用钩子.

>而不是使用跟踪,而是编写一个导入钩子,在导入代码时对其进行修改.最简单的方法可能是在AST级别:解析源之后,使用NodeTransformer在每个def和lambda节点之前或之后注入对某个function2的调用,然后编译转换后的树.但是您也可以在每个MAKE_FUNCTION.3之前或之后在字节码级别使用bytecode或byteplay进行操作.

>编写pdb脚本,而不是编写自己的调试器.我不确定这是否会有所帮助,因为pdb首先没有办法遍历表达式的一部分.

>调试CPython本身,并在调用代码的ceval循环的MAKE_FUNCTION处理程序中添加断点.当然,您的代码在调试器的解释器中-可以是适用于gdb和lldb的Python,但仍不是您要调试的Python解释器.而且,虽然可以将代码递归地评估到调试的解释器中(或触发其pdb),但这并不容易,而且在执行过程中您到处都是段错误.

1.理解(2.x中的列表理解除外)是通过定义然后调用一个函数来实现的.因此,任何依赖MAKE_FUNCTION操作码或类似方法的方法也将在理解时触发,而那些依赖源或AST解析的方法则不会(当然,除非您明确地这样做).

2.显然,您还需要在每个模块的顶部插入一个导入,以使该功能可用,或将该功能插入内置模块.

3.还有MAKE_CLOSURE,用于早期版本的Python.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值