Unicode のサポート
MicroPython は文字列の Unicode をサポートしています。レベル 1、2、3 のすべてのポートはデフォルトで Unicode サポートを有効にしていますが、ビルド構成を変更することで変更することもできます。
用語
This document uses the following Unicode terms:
コードポイント: U+0000 から U+10FFFF の範囲にある単一の Unicode 値。たとえば、U+0041
Aまたは U+1F600 😀 などです。MicroPython の文字列は、コードポイントのシーケンスです。文字: 非公式にはコードポイントを意味します。ユーザーが認識する文字(グラフェム)は、基本文字と結合記号など、複数のコードポイントで構成される場合があることに注意してください。
バイト: 8ビットの単一の値。UTF-8 では、各コードポイントは1~4バイトで格納されます(下記参照)。
len() 、インデックス、スライスなどの操作は、文字や表示幅ではなく、コードポイントに対して作用するため、基本文字の後に結合記号が続く場合は、2つのコードポイントとしてカウントされます。
文字のエンコード
MicroPython は、すべての文字列に UTF-8 エンコーディングを使います。Unicode サポートが有効になっている場合(MICROPY_PY_BUILTINS_STR_UNICODE)、文字列には U+0000 から U+10FFFF までの有効な Unicode コードポイントを含められます。
ASCII文字(0-127)は1バイトに格納されるため、Unicode をサポートしていないシステムと同程度のメモリ効率を実現します。マルチバイト UTF-8 コードポイントは、コードポイントに応じて2~4バイトを使用します。
U+0000 to U+007F: 1 バイト(ASCII)
U+0080 to U+07FF: 2バイト
U+0800 to U+FFFF: 3バイト
U+10000 to U+10FFFF: 4バイト
エンコードとデコード
bytes.decode() と str.encode() メソッドは、次のエンコーディングをサポートしています:
UTF-8 (
'utf-8'または'utf8')ASCII (
'ascii')
その他のエンコーディング('latin-1', 'utf-16' など)はサポートされておらず、 LookupError が発生します。
使用例:
>>> '日本語'.encode('utf-8')
b'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e'
>>> b'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e'.decode('utf-8')
'日本語'
エラー処理
無効な UTF-8 シーケンスを含むバイトをデコードする場合、 bytes.decode() の errors パラメータによって動作が制御されます。
'strict'(デフォルト):UnicodeError例外を発生(
MICROPY_PY_BUILTINS_BYTES_DECODE_ERRORSを有効にしてのビルドが必要)'replace': 無効なバイトを U+FFFD � に置換(MICROPY_PY_BUILTINS_BYTES_DECODE_ERRORSを有効にしてのビルドが必要)
使用例:
>>> # strict モード(デフォルト)ではエラーを発生
>>> b'hello\xffworld'.decode('utf-8')
UnicodeError: invalid UTF-8
>>> # ignore モードは無効なバイトをスキップ
>>> b'hello\xffworld'.decode('utf-8', 'ignore')
'helloworld'
>>> # replace モードは無効なバイトを置換文字に
>>> b'hello\xffworld'.decode('utf-8', 'replace')
'hello�world'
メモリ使用量を重視するアプリケーションでは、信頼できないデータや部分的に破損したデータを処理する際に 'ignore' モードの使用を検討してください。このモードでは、例外を発生させることなく、有効なテキストを復元できます。
バイト列のようなオブジェクトをデコードする場合、 str() コンストラクタを使う場合も含め、同じエラー処理が適用されます(たとえば buf がバイト列、バイト配列、メモリビュー、または配列オブジェクトである場合の str(buf, 'utf-8', 'replace') など)。
文字列のメソッド
Unicode サポートが有効になっている場合、文字列メソッドはバイトではなくコードポイントに対して動作します:
str.center()- 幅の計算のためにコードポイントをカウントします。len(s)- コードポイントの数を返します(バイトではありません)。文字列のインデックスとスライスはコードポイントの境界で動作します。
表示幅の計算はサポートしていません(東アジアの幅、文字の結合など)。
使用例:
>>> s = 'Hello 世界'
>>> len(s) # 8 コードポイント
8
>>> len(s.encode()) # 12 バイト
12
>>> s.center(12) # コードポイントのカウントによる中央寄せ
' Hello 世界 '
文字列のフォーマット
%c フォーマット指定子と {:c} フォーマットコードは完全な Unicode をサポートします:
0 から 0x10FFFF までのコードポイントを受け入れます。
マルチバイト UTF-8 コードポイントを適切にエンコードします。
無効なコードポイントの場合は ValueError を発生させます。
使用例:
>>> '%c' % 65 # ASCII
'A'
>>> '%c' % 0x03B1 # ギリシャ語 α
'α'
>>> '%c' % 0x1F600 # 絵文字 😀
'😀'
>>> '{:c}'.format(0x4E2D) # 中国語 中
'中'
>>> # 無効なコードポイント
>>> '%c' % 0x110000
ValueError: %c arg not in range(0x110000)
f文字列も :c フォーマットコードをサポートしています:
>>> code_point = 0x2665 # Heart suit ♥
>>> f'I {code_point:c} Python'
'I ♥ Python'
ビルド設定
Unicode機能は mpconfigport.h にあるいくつかのビルド時フラグによって制御されます:
MICROPY_PY_BUILTINS_STR_UNICODEUnicode 文字列サポートを有効にします。有効にすると、文字列には有効な Unicode 文字を含めることができ、文字列操作はバイト境界ではなく文字境界で行われます。
デフォルト:
MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES以上で有効。レベル 1、2、3 のすべてのポートで有効。
MICROPY_PY_BUILTINS_STR_UNICODE_CHECK文字列操作時に UTF-8 検証を有効にします。無効にすると、無効なUTF-8シーケンスで文字列操作の結果が正しくない場合があります。
デフォルト:
MICROPY_PY_BUILTINS_STR_UNICODE設定にしたがい。レベル 1、2、3 のすべてのポートで有効。
MICROPY_PY_BUILTINS_BYTES_DECODE_ERRORSbytes.decode()のエラー ハンドラ'ignore'と'replace'を有効にします。有効にすると、無効な UTF-8 バイトはスキップ('ignore')するか、U+FFFD に置き換える('replace')ことができます。デフォルト:
MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES以上で有効。alif、esp32、esp8266、mimxrt、renesas-ra、rp2、samd (SAMD51 のみ)、stm32、unix、webassembly ポートで有効。
ビルド設定の例
フラッシュメモリ容量が制限された制約のあるポートでは、エラーハンドラを無効にします:
#define MICROPY_PY_BUILTINS_BYTES_DECODE_ERRORS (0)
リソースが豊富なポートの場合は、すべての Unicode 機能を有効にします:
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)
// これにより、以下が自動的に有効になります::
// - MICROPY_PY_BUILTINS_STR_UNICODE
// - MICROPY_PY_BUILTINS_BYTES_DECODE_ERRORS
制限事項
MicroPython の Unicodeサポートは、CPythonと比較していくつかの制限があります:
UTF-8 と ASCII エンコーディングのみをサポート
Unicode 正規化のサポートなし
ロケールを考慮した文字列操作のサポートなし
errorsパラメータは位置引数でのみ受け付け(キーワード引数は受け付けない)。upper(),lower()などの文字列メソッドは ASCII でのみ正しく動作MicroPython の対話型REPLと
input()関数は、現在 Unicode のサポートが限定的です。行エディタは文字の表示幅を認識しません。幅の広い文字(たとえば、多くのCJK文字)は2つの終端列を占めますが、文字クラスター(基本コードポイントと結合記号、または絵文字シーケンス)は複数のコードポイントにまたがっても1つの列を占めることがあります。編集では表示される列ではなくコードポイントが追跡されるため、バックスペースキーや左右の矢印キーなどの行編集キーを使うと、カーソルが画面に表示されるテキストとずれてしまうことがあります。この問題を回避するには、Unicode テキストを UTF-8 エンコードした MicroPython スクリプトに配置し、mpremote run <script.py>で実行します。