运行 Python shell 中的逐行脚本与原子方式
Run Python script line-by-line in shell vs atomically
我正在将 MicroPython 集成到微控制器中,我想为我的产品添加调试逐步执行模式(通过与 PC 的连接)。
值得庆幸的是,MicroPython 包含一个 REPL 又名 Python shell 功能:我可以一次输入一行并执行。
我想用这个功能在PC端单步执行,然后将Python脚本中的行逐行发送。
任何差异,除了可能的时间,运行和Python脚本一行之间一次 vs python my_script.py
?
Is there ANY difference ...
是的。
例如,下面的代码在 .py
文件中有效,但在交互式解释器中是 SyntaxError
:
x = 1
if x == 1:
pass
x = 2
还有 许多 其他差异,但仅这一点就足以让您放弃这个想法。
不知道MicroPython有没有内置compile()和exec()。
但是当嵌入式 Python 有它们并且当 MCU 有足够的 RAM 时,我会执行以下操作:
向嵌入发送一行 shell 以开始使用多行字符串创建变量。
'_code = """\'
发送我希望执行的代码(逐行或无论如何)
用“”结束多行字符串
向运行发送exec命令到MCU变量中存储的传输代码并获取输出。
如果您的 RAM 很小并且您不能一次传输整个代码,您应该将其分块传输以供执行。比如函数、循环等
如果您可以在 PC 上为 MicroPython 编译字节码,那么您应该可以传输它并准备执行。这将使用更少的 RAM。
但是是否可以将原始字节码注入 shell 和 运行 取决于 MicroPython 与 CPython.
的相似程度
是的,存在差异。正如在另一个答案中解释的那样,逐行执行可能很棘手。所以代码块是你最好的选择。
在 stdin 上一次传递一行代码是完全不可接受的正确调试器替代方案。
假设您要调试以下内容:
def foo(): # 1
for i in range(10): # 2
if i == 5: # 3
raise Exception("Argh!") # 4
# 5
foo() # 6
...在正确的逐步调试器中,用户可以像这样使用它:
break 4
run
现在,你打算怎么做?如果您在 REPL 中输入该函数,则该函数被定义为一个操作,并且它作为一个操作运行。它不会在第 6 行停止。它不会让您逐行进行。 for
循环也是如此:一次一行输入 for
循环的文本不会让您在抛出异常之前单步执行它。
如果您消除函数并消除循环(生成代码 _something = iter(range(10)); i=_something.next()
,也许吧?),那么您需要模拟作用域的影响。这意味着您使用的语言与您声称的语言截然不同"debugging"。
我正在将 MicroPython 集成到微控制器中,我想为我的产品添加调试逐步执行模式(通过与 PC 的连接)。
值得庆幸的是,MicroPython 包含一个 REPL 又名 Python shell 功能:我可以一次输入一行并执行。
我想用这个功能在PC端单步执行,然后将Python脚本中的行逐行发送。
任何差异,除了可能的时间,运行和Python脚本一行之间一次 vs python my_script.py
?
Is there ANY difference ...
是的。
例如,下面的代码在 .py
文件中有效,但在交互式解释器中是 SyntaxError
:
x = 1
if x == 1:
pass
x = 2
还有 许多 其他差异,但仅这一点就足以让您放弃这个想法。
不知道MicroPython有没有内置compile()和exec()。 但是当嵌入式 Python 有它们并且当 MCU 有足够的 RAM 时,我会执行以下操作:
向嵌入发送一行 shell 以开始使用多行字符串创建变量。
'_code = """\'
发送我希望执行的代码(逐行或无论如何)
用“”结束多行字符串
向运行发送exec命令到MCU变量中存储的传输代码并获取输出。
如果您的 RAM 很小并且您不能一次传输整个代码,您应该将其分块传输以供执行。比如函数、循环等
如果您可以在 PC 上为 MicroPython 编译字节码,那么您应该可以传输它并准备执行。这将使用更少的 RAM。 但是是否可以将原始字节码注入 shell 和 运行 取决于 MicroPython 与 CPython.
的相似程度是的,存在差异。正如在另一个答案中解释的那样,逐行执行可能很棘手。所以代码块是你最好的选择。
在 stdin 上一次传递一行代码是完全不可接受的正确调试器替代方案。
假设您要调试以下内容:
def foo(): # 1
for i in range(10): # 2
if i == 5: # 3
raise Exception("Argh!") # 4
# 5
foo() # 6
...在正确的逐步调试器中,用户可以像这样使用它:
break 4
run
现在,你打算怎么做?如果您在 REPL 中输入该函数,则该函数被定义为一个操作,并且它作为一个操作运行。它不会在第 6 行停止。它不会让您逐行进行。 for
循环也是如此:一次一行输入 for
循环的文本不会让您在抛出异常之前单步执行它。
如果您消除函数并消除循环(生成代码 _something = iter(range(10)); i=_something.next()
,也许吧?),那么您需要模拟作用域的影响。这意味着您使用的语言与您声称的语言截然不同"debugging"。