草庐IT

python - 逐步跟踪 Python 表达式求值

coder 2023-08-15 原文

我正在尝试编写 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

此处 >><< 用于突出显示在当前步骤中计算的表达式的一部分,然后由其值替换。 (也许,稍后我会尝试将此序列转换为某种动画。)

我目前的策略是使用ast.parse()将字符串解析成AST,然后找到一个要先求值的节点,用eval(compile(node, '', 'eval'))求值(我绝对不想重新实现整个Python :)),转换将评估结果放入 AST 节点(先是 repr,然后是 ast.parse()?),然后用结果节点替换当前节点,然后使用 codegen.to_source 从(修改后的)AST 生成修改后的代码字符串,并继续相同的过程,直到我在树中只有一个文字.

我的问题是:我怎样才能找到一个将首先被评估的节点?似乎我可以通过子类化 ast.NodeVisitor 深度优先遍历树,但我不确定如何检测到我到达了所需的节点以及如何在它之后停止遍历?


编辑。

我最初的树转换方法可能不可行。事实上,Python 表达式求值的基本步骤不一定是将某些子表达式替换为更简单的表达式(如算术)。例如,列表理解提供了一种更复杂的行为,不能用术语用那个东西替换这个东西,然后递归地重复来表达。所以我稍微重申一下这个问题。我需要一些方法来以编程方式展示如何逐步评估 Python 表达式。例如,@jasonharper 提到的 MacroPy 的 tracing 功能是现阶段可接受的解决方案。不幸的是,MacroPy 似乎已被放弃并且无法与 Python 3 一起使用。是否有任何想法如何在不移植完整 MacroPy 的情况下类似于 Python 3 中的这种跟踪行为?


EDIT2.

就在我授予此赏金之后,我发现了 similar question 和一个具有非常接近特征的 debugger。但是,由于该问题没有最终答案,而且我不需要完整的调试器,我仍在寻找可以在 Jupyter 环境中使用的答案。

最佳答案

表达式步进在 Thonny IDE 中实现.

它使用 AST 检测,其中每个(子)表达式 e转化为after(before(<location info>), e) .功能beforeafter是在 Python 的跟踪系统中引起额外的 call 事件的虚拟函数。这些额外的调用会在(子)表达式计算即将开始或刚刚结束时发出通知。 (添加了类似的虚拟函数来检测每个语句的开始和结束。)

这些新事件的 AST 检测和解释在 thonny.backend.FancyTracer 中完成.

Python 的 AST 节点包含相应文本范围的起始位置,但它们有时不正确。结束位置完全缺失。 thonny.ast_utils.mark_text_ranges试图解决这个问题(但目前解决方案不完整)。

如果有人将相关功能从 Thonny 提取到一个更通用的包中,那就太好了。甚至可能有两个包——一个用于计算 Python AST 的位置信息,另一个用于详细跟踪 Python 代码。如果有人带头,我愿意为此提供帮助。

关于python - 逐步跟踪 Python 表达式求值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40639652/

有关python - 逐步跟踪 Python 表达式求值的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  3. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  8. ruby - 正则表达式将非英文字母匹配为非单词字符 - 2

    @raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://

  9. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  10. Python 刷Leetcode题库,顺带学英语单词(31) - 2

    ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem

随机推荐