MicroPython 対話型インタープリタモード(別名 REPL)

このセクションでは、MicroPython 対話型インタープリタモードのいくつかの特徴について説明します。これは一般に REPL(read-eval-print-loop、読み取り・評価・出力ループ)と呼ばれており、本書ではこの対話型プロンプトを指す用語として使用します。

注釈

OpenMV Cam はこの REPL を USB シリアル(CDC)ポート経由で公開します。これはシリアルターミナルエミュレータ(または MicroPython リモートコントロール: mpremote などのツール)でカメラに直接接続する場合にのみ関係します。OpenMV IDE は REPL を使用しません — スクリプトの実行、ファイルの転送、フレームバッファのストリーミングには、別個のデバッグプロトコルを介してカメラと通信します。このページで説明する内容はすべて、直接のターミナルセッションにのみ適用されます。

自動インデント

コロンで終わる Python 文(たとえば if、for、while)を入力すると、プロンプトが 3 つのドット(...)に変わり、カーソルが 4 スペース分インデントされます。Enter を押すと、通常の文では同じインデントレベルで次の行が続き、適切な場合にはさらに 1 段階インデントが追加されます。Backspace キーを押すと、インデントが 1 段階解除されます。

カーソルが行頭まで戻った状態で Enter を押すと、それまでに入力したコードが実行されます。次の例は、for 文を入力した後に表示される内容を示しています(アンダースコアはカーソルが最終的にどこに来るかを示します):

>>> for i in range(30):
...     _

続けて if 文を入力すると、さらに 1 段階のインデントが追加されます:

>>> for i in range(30):
...     if i > 3:
...         _

次に break を入力して Enter を押し、Backspace を押します:

>>> for i in range(30):
...     if i > 3:
...         break
...     _

最後に print(i) と入力し、Enter を押し、Backspace を押してから、もう一度 Enter を押します:

>>> for i in range(30):
...     if i > 3:
...         break
...     print(i)
...
0
1
2
3
>>>

直前の 2 行がすべてスペースだった場合は、自動インデントは適用されません。これは、複合文の入力を Enter を 2 回押すことで終了でき、3 回目の押下で入力を完了して実行できることを意味します。

自動補完

REPL でコマンドを入力している際に、ここまで入力した行が何かの名前の先頭に一致する場合、TAB を押すと入力可能な候補が表示されます。たとえば、まず import machine と入力して Enter を押し、machine モジュールをインポートします。次に m と入力して TAB を押すと、machine に展開されるはずです。ドット . を入力してもう一度 TAB を押します。すると、次のような表示が見られるはずです:

>>> machine.
__name__        info            unique_id       reset
bootloader      freq            rng             idle
sleep           deepsleep       disable_irq     enable_irq
Pin

候補が複数存在するようになるまで、単語は可能な限り展開されます。たとえば machine.Pin.PULL と入力して TAB を押すと machine.Pin.PULL_ に展開されます。もう一度 TAB を押すと、展開候補が表示されます:

>>> machine.Pin.PULL_
PULL_DOWN       PULL_UP
>>> machine.Pin.PULL_

実行中のプログラムの中断

Ctrl-C を押すことで、実行中のプログラムを中断できます。これにより KeyboardInterrupt が発生し、REPL に戻ります。ただし、プログラムが KeyboardInterrupt 例外をインターセプトしていない場合に限ります。

例:

>>> for i in range(1000000):
...     print(i)
...
0
1
2
3
...
6466
6467
6468
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
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 "<stdin>", 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 インタープリタをリセットしますが、OpenMV Cam に接続している方式(USB)はリセットしないようにします。

REPL からは Ctrl-D を押すことで、または Python コードからは次を実行することで、ソフトリセットを実行できます:

machine.soft_reset()

たとえば、OpenMV Cam をリセットして dir() コマンドを実行すると、次のような表示になります:

>>> dir()
['__name__']

次に、いくつかの変数を作成して dir() コマンドを繰り返します:

>>> i = 1
>>> j = 23
>>> x = 'abc'
>>> dir()
['j', 'x', '__name__', 'i']
>>>

ここで Ctrl-D を入力して dir() コマンドを繰り返すと、変数がもう存在しないことがわかります:

MPY: sync filesystems
MPY: soft reboot
MicroPython v1.25.0 on 2025-05-15; OpenMV Cam H7 with STM32H743
Type "help()" for more information.
>>> dir()
['__name__']
>>>

リセットの種類と起動プロセスの詳細については、リセットとブートシーケンス を参照してください。

特殊変数 _(アンダースコア)

REPL を使用すると、計算を実行してその結果を確認できます。MicroPython は直前の文の結果を変数 _(アンダースコア)に格納します。そのため、アンダースコアを使って結果を変数に保存できます。例:

>>> 1 + 2 + 3 + 4 + 5
15
>>> x = _
>>> x
15
>>>

raw モードと raw-paste モード

raw モード(raw REPL とも呼ばれます)は、通常は人が使うものではありません。プログラムによる使用を意図しており、本質的にはエコーをオフにしたペーストモードのように動作し、オプションでフロー制御も行います。

raw モードには Ctrl-A を使って入ります。続いて Python コードを送信し、その後に Ctrl-D を送ります。Ctrl-D は「OK」で確認され、その後 Python コードがコンパイルされて実行されます。出力(またはエラー)はすべて返送されます。Ctrl-B を入力すると raw モードを終了し、通常の(別名フレンドリーな)REPL に戻ります。

raw-paste モードは raw REPL 内の追加モードであり、フロー制御を含み、コードを受信しながらコンパイルします。これにより、デバイスへの高速なコード転送に対してより堅牢になります。また、コンパイル前にコードの全コピーを保存する必要がない(標準の raw モードとは異なり)ため、受信時に使用する RAM も少なくて済みます。

raw-paste モードは次のプロトコルを使用します:

  1. 通常どおり ctrl-A を使って raw REPL に入ります。

  2. 3 バイトを書き込みます: b"\x05A\x01"(つまり ctrl-E、続いて「A」、続いて ctrl-A)。

  3. 2 バイトを読み取り、デバイスが raw-paste モードに入ったかどうかを判断します:

    • 結果が b"R\x00" の場合、デバイスはコマンドを理解していますが、raw paste をサポートしていません。

    • 結果が b"R\x01" の場合、デバイスは raw paste をサポートしており、このモードに入っています。

    • それ以外の場合、結果は b"ra" であるはずで、デバイスは raw paste をサポートしていません。この場合、文字列 b"w REPL; CTRL-B to exit\r\n>" を読み取って破棄する必要があります。

  4. デバイスが raw-paste モードである場合は続行し、そうでない場合は標準の raw モードにフォールバックします。

  5. 2 バイトを読み取ります。これは 16 ビット符号なしリトルエンディアン整数として格納されたフロー制御のウィンドウサイズ増分(バイト単位)です。残りウィンドウサイズ変数の初期値は、この数値に設定する必要があります。

  6. コードをデバイスに書き出します:

    • 送信すべきバイトがある間は、残りウィンドウサイズ分までのバイトを書き込み、書き込んだバイト数だけ残りウィンドウサイズを減らします。

    • 残りウィンドウサイズが 0 であるか、読み取り待ちのバイトがある場合は、1 バイトを読み取ります。このバイトが b"\x01" の場合は、ステップ 5 のウィンドウサイズ増分だけ残りウィンドウサイズを増やします。このバイトが b"\x04" の場合は、デバイスがデータ受信の終了を望んでいるため、b"\x04" をデバイスに書き込み、その後はコードを送信しません。(注意:デバイスから読み取り待ちのバイトがある場合でも、それを直ちに読み取って処理する必要はありません。残りウィンドウサイズが 0 より大きい限り、デバイスは入ってくるバイトを消費し続けます。)

  7. すべてのコードをデバイスに書き込んだら、b"\x04" を書き込んでデータの終了を示します。

  8. b"\x04" を受信するまでデバイスから読み取ります。この時点で、デバイスは送信されたすべてのコードを受信してコンパイルし、それを実行しています。

  9. デバイスは、実行中のコードが生成した文字をすべて出力します。コードが終了すると(終了した場合)、b"\x04" が出力され、続いて捕捉されなかった例外が出力され、さらに再び b"\x04" が出力されます。その後、標準の raw 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>"

時間経過で分解すると、これは次のようになります:

# Step 1: enter raw REPL
write: b"\x01"
read: b"\r\nraw REPL; CTRL-B to exit\r\n>"

# Step 2-5: enter raw-paste mode
write: b"\x05A\x01"
read: b"R\x01\x80\x00\x01"

# Step 6-8: write out code
write: b"print(123)\x04"
read: b"\x04"

# Step 9: code executes and result is read
read: b"123\r\n\x04\x04>"

この場合、フロー制御のウィンドウサイズ増分は 128 であり、開始時点では即座に 2 ウィンドウ分のデータが利用可能です。1 つは初期のウィンドウサイズ増分の値によるもの、もう 1 つは送信される明示的な b"\x01" の値によるものです。つまり、待機したり追加の入力フロー制御文字を確認したりする前に、最初に最大 256 バイトまで書き込めるということです。

MicroPython リモートコントロール: mpremote ツールは、OpenMV Cam 上で Python コードを実行するために、raw-paste モードを含む raw REPL を使用します。