我正在尝试编写Python表达式评估可视化工具,它将显示如何逐步评估Python表达式(用于教育目的).Philip Guo的Python Tutor很棒,但它逐行评估Python程序,我发现学生有时不理解单行表达式sorted([4, 2, 3, 1] + [5, 6])[1] == 2是如何评估的,我想要想象这个过程.(似乎没有人做过 - 至少我什么也没发现.)理想的解决方案是创建一系列字符串,如下所示:
sorted([4, 2, 3, 1] + [5, 6])[1] == 2
sorted( >> [4, 2, 3, 1] + [5, 6] << )[1] == 2
>> sorted([4, 2, 3, 1, 5, 6]) << [1] == 2
>> [1 2 3 4 5 6][1] << == 2
>> 2 == 2 <<
True
Run Code Online (Sandbox Code Playgroud)
这里>>和<<用来突出显示对当前步骤评估,然后通过它的值替换表达式的一部分.(也许,我会尝试将此序列转换为某种动画.)
我当前的策略是使用ast.parse()将字符串解析为AST,然后找到一个将首先评估的节点,用它评估它eval(compile(node, '', 'eval'))(我绝对不想重新实现整个Python :)),将评估结果转换为AST节点(有repr,然后ast.parse() …
在内部跟踪功能,调试函数调用时,是否可以以某种方式检索调用表达式?
我可以从traceback对象中调用行号,但如果该行上有多个函数调用(可能是相同的函数)(例如,作为更大表达式中的子表达式),那么我怎样才能知道这个调用的来源?即使从源线的起点偏移,我也会很高兴.
traceback.tb_lasti 似乎给出了更多的粒度上下文(尝试了最后一个字节码的索引) - 是否有可能将字节码连接到其确切的源范围?
编辑:只是为了澄清 - 我需要从调用源代码行中提取特定的(子)表达式(调用点).