MicroPython的交互式解释器模式 (又称REPL) ======================================================= 此部分介绍了MicroPython的交互式解释器模式的特性,其常用术语为REPL(读取read-评估eval-打印print-循环loop),用于指代此交互式提示符。 自动-缩进 ----------- 当键入以冒号(例如:if、for、while)结尾的python语句时,提示符将变为三个点(...),光标将缩进4个空格。 当您点击返回键,下一行将继续在正常语句缩进的同一级别,或在适当的情况下继续添加缩进级别。若您点击退格键,则将撤销一个缩进级别。 若您的光标一直停在开始时,点击返回键将执行您输入的代码。以下演示了您在输入for语句后将看到的(下划线显示光标的位置): >>> for i in range(30): ... _ 若您输入if语句,则将提供额外的缩进级别: >>> for i in range(30): ... if i > 3: ... _ 现在输入 ``break`` ,然后点击回车键,再点击退格键: >>> for i in range(30): ... if i > 3: ... break ... _ 最后,键入 ``print(i)`` ,依次点击回车键、退格键和回车键: >>> for i in range(30): ... if i > 3: ... break ... print(i) ... 0 1 2 3 >>> 若前两行都为空格,则不会应用自动缩进。这意味着您可以通过点击两次返回来完成复合语句输入,然后第三次按键结束并执行。 自动-完成 --------------- 当在REPL中输入指令时,如果输入的行对应某物名称的开头,点击TAB键将显示您可能输入的内容。 首先通过输入 ``import machine`` 并按RETURN来导入机器模块。 键入 ``m`` 并点击TAB,则其将扩展为 ``machine`` 。键入一个点 ``.`` 并点击TAB,您将看到如下: >>> machine. __name__ info unique_id reset bootloader freq rng idle sleep deepsleep disable_irq enable_irq Pin 该词将尽可能扩展,直至出现多种可能性。例如:键入 ``machine.Pin.AF3`` 并点击TAB键, 则其将扩展为 ``machine.Pin.AF3_TIM`` 。长按TAB一秒,则显示可能的扩展: >>> machine.Pin.AF3_TIM AF3_TIM10 AF3_TIM11 AF3_TIM8 AF3_TIM9 >>> machine.Pin.AF3_TIM 中断一个运行程序 ------------------------------ 您可通过点击Ctrl-C来中断一个运行程序。这将引发键盘中断,使您返回REPL,前提是您的程序不会阻截键盘中断故障。 例如: >>> for i in range(1000000): ... print(i) ... 0 1 2 3 ... 6466 6467 6468 Traceback (most recent call last): File "", line 2, in KeyboardInterrupt: >>> 粘贴模式 ---------- 若您想将某些代码粘贴到您的终端窗口中,自动缩进特性将会成为障碍。例如,若您有以下python代码: :: def foo(): print('This is a test to show paste mode') print('Here is a second line') foo() 您试图将此代码粘贴到常规REPL中,那么您将会看到以下内容: >>> def foo(): ... print('This is a test to show paste mode') ... print('Here is a second line') ... foo() ... Traceback (most recent call last): File "", line 3 IndentationError: unexpected indent 若您点击Ctrl-E,则将进入粘贴模式,即关闭自动缩进特性,并将提示符从 ``>>>`` 更改为 ``===`` 。例如: >>> paste mode; Ctrl-C to cancel, Ctrl-D to finish === def foo(): === print('This is a test to show paste mode') === print('Here is a second line') === foo() === This is a test to show paste mode Here is a second line >>> 粘贴模式允许粘贴空白行,将被粘贴文本作为文件编译。点击Ctrl-D退出粘贴模式,并启动编译。 软复位 ---------- 软复位将重置python的解释器,但不会重置您连接到MicroPython板的方法(USB-串口或WiFi)。 您可点击Ctrl-D从REPL进行软复位,或从您的python代码中执行: :: machine.soft_reset() 例如:若您重置您的MicroPython板,并执行dir()指令,您将看到如下内容: >>> dir() ['__name__', 'pyb'] 现在创建一些变量,并重复dir()指令: >>> i = 1 >>> j = 23 >>> x = 'abc' >>> dir() ['j', 'x', '__name__', 'pyb', 'i'] >>> 现在,若您点击Ctrl-D,并重复dir()指令,您将发现变量不复存在: .. code-block:: python MPY: sync filesystems MPY: soft reboot MicroPython v1.5-51-g6f70283-dirty on 2015-10-30; PYBv1.0 with STM32F405RG Type "help()" for more information. >>> dir() ['__name__', 'pyb'] >>> 特殊变量 _ (下划线) ----------------------------------- 使用REPL时,进行计算并得到结果。MicroPython将之前语句的结果储存到变量_(下划线)中。您可使用下划线将结果储存到变量中。例如: >>> 1 + 2 + 3 + 4 + 5 15 >>> x = _ >>> x 15 >>> 原始模式和原始粘贴模式 --------------------------- 原始模式(也称为原始 REPL)不是人们通常会使用的东西。 它旨在用于编程用途,本质上类似于粘贴模式,关闭了回声,并具有可选的流量控制。 点击Ctrl-A进入原始模式。发送您的python代码,然后点击Ctrl-D。Ctrl-D键将识别为"确定",然后编译并执行python 代码。 所有输出(或故障)都会发送回去。点击Ctrl-B将会退出原始模式,并返回常规(又称友好型)REPL。 原始粘贴模式是原始 REPL 中的一种附加模式,它包括流控制,并在收到代码时对其进行编译。 这使得它在将代码高速传输到设备时更加鲁棒, 并且在接收时也使用更少的 RAM,因为它不需要在编译前存储代码的逐字副本(与标准原始模式不同)。 原始粘贴模式使用以下协议: #. 像往常一样通过 ctrl-A 进入原始 REPL。 #. 写入 3 个字节: ``b"\x05A\x01"`` (即 ctrl-E 然后是“A”然后是 ctrl-A)。 #. 读取 2 个字节以确定设备是否进入原始粘贴模式: * 如果结果是 ``b"R\x00"`` 则设备理解命令但不支持原始粘贴。 * 如果结果是 ``b"R\x01"`` 那么设备确实支持原始粘贴并已进入此模式。 * 否则结果应该是 ``b"ra"`` 并且设备不支持原始粘贴且应该读取字符串 ``b"w REPL; CTRL-B to exit\r\n>"`` 并丢弃。 #. 如果设备处于原始粘贴模式,则继续,否则回退到标准原始模式。 #. 读取 2 个字节,这是存储为 16 位无符号小端整数的流控制窗口大小增量(以字节为单位)。 剩余窗口大小变量的初始值应设置为此数字。 #. 将代码写入设备: * 当有字节要发送时,写入剩余窗口大小的字节数,并将剩余窗口大小减少写入的字节数。 * 如果剩余窗口大小为 0,或者有字节等待读取,则读取 1 个字节。 如果此字节是 ``b"\x01"`` 则将剩余窗口大小增加第 5 步的窗口大小增量。 如果此字节是 ``b"\x04"`` 那么设备想要 结束数据接收,并且 ``b"\x04"`` 应该写入设备,之后不再发送任何代码。 (注意:如果有一个字节等待从设备读取,那么它不需要立即读取和操作,只要 reaming-window-size 大于 0,设备将继续消耗传入的字节。) #. 当所有代码都写入设备后,写入 ``b"\x04"`` 以指示数据结束。 #. 从设备读取,直到收到 ``b"\x04"``。 此时,设备已经接收并编译了所有发送并正在执行的代码。 #. 设备输出由执行代码产生的任何字符。 当(如果)代码完成时,将输出 ``b"\x04"``,然后是任何未捕获的异常,然后是 ``b"\x04"``。 然后它返回到标准的原始 REPL 并输出 ``b">"``。 例如,在正常的(友好的)REPL 处从新行开始,如果你写: b"\x01\x05A\x01print(123)\x04" 然后设备将响应如下:: b"\r\nraw REPL; CTRL-B to exit\r\n>R\x01\x80\x00\x01\x04123\r\n\x04\x04>" 随着时间的推移,这看起来像:: # 第 1 步:输入原始 REPL write: b"\x01" read: b"\r\nraw REPL; CTRL-B to exit\r\n>" # 步骤 2-5:进入原始粘贴模式 write: b"\x05A\x01" read: b"R\x01\x80\x00\x01" # Step 6-8: 输出代码 write: b"print(123)\x04" read: b"\x04" # Step 9: 代码执行并读取结果 read: b"123\r\n\x04\x04>" 在这种情况下,流控制窗口大小增量是 128 并且在开始时有两个窗口立即可用的数据,一个来自初始窗口大小增量值,另一个来自显式“b”\x01” ` 发送的值。 所以这意味着在等待或检查更多传入的流控制字符之前,最多可以写入 256 个字节。 ``tools/pyboard.py`` 程序使用原始 REPL,包括原始粘贴模式,在支持 MicroPython 的板上执行 Python 代码。