Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在shell中逐行运行Python脚本vs原子运行_Python_Micropython - Fatal编程技术网

在shell中逐行运行Python脚本vs原子运行

在shell中逐行运行Python脚本vs原子运行,python,micropython,Python,Micropython,我正在将MicroPython集成到微控制器中,我想向我的产品(通过与PC的连接)添加一个调试逐步执行模式 谢天谢地,MicroPython包含了一个REPLakapythonshell功能:我可以一次输入一行代码并执行 我想使用此功能在PC端单步执行,并在Python脚本中一行一行地发送 一次运行一行Python脚本与Python my_script.py之间除了可能的时间安排之外,还有什么区别吗 有什么不同吗 对 例如,下面的代码在.py文件中工作,但在交互式解释器中是一个SyntaxErr

我正在将MicroPython集成到微控制器中,我想向我的产品(通过与PC的连接)添加一个调试逐步执行模式

谢天谢地,MicroPython包含了一个REPLakapythonshell功能:我可以一次输入一行代码并执行

我想使用此功能在PC端单步执行,并在Python脚本中一行一行地发送

一次运行一行Python脚本与
Python my_script.py
之间除了可能的时间安排之外,还有什么区别吗

有什么不同吗

例如,下面的代码在
.py
文件中工作,但在交互式解释器中是一个
SyntaxError

x = 1
if x == 1:
    pass
x = 2

还有很多不同之处,但仅此一点就足以吓跑你

我不知道MicroPython是否内置了compile()和exec()。 但是,当嵌入式Python拥有它们并且MCU拥有足够的RAM时,我会执行以下操作:

def foo():                            # 1
    for i in range(10):               # 2
        if i == 5:                    # 3
            raise Exception("Argh!")  # 4
                                      # 5
foo()                                 # 6
  • 向嵌入的shell发送一行,开始创建具有多行字符串的变量

    “\u 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
    循环的文本一行,不允许在引发异常之前对其进行单步处理


    如果消除函数并消除循环(生成代码
    \u something=iter(范围(10));i=\u something.next()
    ,可能?),则需要模拟作用域的效果。这意味着你的语言与你所谓的“调试”语言截然不同;为什么你的例子在shell中失败了?很复杂。你真的不需要了解,我想了解,这样我就可以确定这是否只是几个角落的案子,而不仅仅是几个角落的案子。您应该找到一种更好的方法来编写调试器,例如使用@wim,……不幸的是,它看起来像是
    sys.settrace()
    在micropython中不可用,例如。这并不意味着我支持OP提议的黑客行为,而不是正确地实现必要的VM支持。假设你有一个循环。您是否打算让自己的解释器管理流控制?因为否则,你不能一次跨一行——要么整个循环运行,要么一行都不运行。实际上,这意味着你需要更多的东西才能获得单步执行的效果:实际上,你需要在可能设置断点的任何位置注入新的函数调用。可以想象通过插入代码(理想情况下,解析并以编程方式修改AST)来实现这一点,但这将是一个糟糕的局面,我不理解这样一句话:
    一次输入for循环的文本一行,不允许在抛出异常之前进行步进。
    Nvm我明白了:这是整个流控制问题。对,对。一旦调用
    foo()
    ,所有
    foo
    都会运行,它不会一次运行一行。如果我向它发送代码块呢?i、 e.如果块,对于块,等等(1)这意味着您需要模拟在代码上输入和离开函数作用域的所有影响(这些影响并不总是明显的),以及(2)块仍然一次运行,而不是一行一行。如果我做了代码块,这将绕过提到的问题?应该这样做。但是,如果您正在逐块执行,那么在引发异常时,您必须不断更正行号。如果您真的想一个命令一个命令地执行所有命令并跟踪整个过程,恐怕您没有其他选择,只能获取代码,使用AST,在每个命令进入AST后调用添加的跟踪函数,编译AST,然后将字节码发送给MCU并运行它。这并不像听起来那么难实现。