运行 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 时,我会执行以下操作:

  1. 向嵌入发送一行 shell 以开始使用多行字符串创建变量。

    '_code = """\'

  2. 发送我希望执行的代码(逐行或无论如何)

  3. 用“”结束多行字符串

  4. 向运行发送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"。