7.8. codecs --- codec レジストリと基底クラス

このモジュールでは、内部的な Python codec レジストリに対するアクセス手段を提供しています。codec レジストリは、標準の Python codec(エンコーダとデコーダ)の基底クラスを定義し、 codec およびエラー処理の検索手順を管理しています。

codecs では以下の関数を定義しています:

codecs.encode(obj[, encoding[, errors]])

encoding に記載された codec を使用して obj をエンコードします。デフォルトのエンコーディングは 'ascii' です。

希望のエラー処理スキームを errors に設定することができます。デフォルトのエラーハンドラは 'strict' です。これはエンコードエラーは ValueError (もしくは UnicodeEncodeError のような、より codec に固有のサブクラス) を送出することを意味します。codec エラー処理についてのより詳しい情報は Codec 基底クラス を参照してください。

バージョン 2.4 で追加.

codecs.decode(obj[, encoding[, errors]])

encoding に記載された codec を使用して obj をデコードします。デフォルトのエンコーディングは 'ascii' です。

希望のエラー処理スキームを errors に設定することができます。デフォルトのエラーハンドラは 'strict' です。これはデコードエラーは ValueError (もしくは UnicodeDecodeError のような、より codec に固有のサブクラス) を送出することを意味します。codec エラー処理についてのより詳しい情報は Codec 基底クラス を参照してください。

バージョン 2.4 で追加.

codecs.register(search_function)

codec 検索関数を登録します。検索関数は第 1 引数にアルファベットの小文字から成るエンコーディング名を取り、以下の属性を持つ CodecInfo オブジェクトを返します:

  • name エンコーディング名;

  • encode 内部状態を持たないエンコード関数;

  • decode 内部状態を持たないデコード関数;

  • incrementalencoder 漸増的エンコーダクラスまたはファクトリ関数;

  • incrementaldecoder 漸増的デコーダクラスまたはファクトリ関数;

  • streamwriter ストリームライタクラスまたはファクトリ関数;

  • streamreader ストリームリーダクラスまたはファクトリ関数。

種々の関数やクラスが以下の引数をとります:

encodedecode: これらの引数は、 Codec インスタンスの encode()decode() と同じインタフェースを持つ関数、またはメソッドでなければなりません (Codec Interface 参照) 。これらの関数・メソッドは内部状態を持たずに動作する (stateless mode) と想定されています。

incrementalencoderincrementaldecoder: これらは以下のインタフェースを持つファクトリ関数でなければなりません:

factory(errors='strict')

ファクトリ関数は、それぞれ基底クラスの IncrementalEncoderIncrementalDecoder が定義しているインタフェースを提供するオブジェクトを返さなければなりません。漸増的 codecs は内部状態を維持できます。

streamreaderstreamwriter: これらの引数は、次のようなインタフェースを持つファクトリ関数でなければなりません:

factory(stream, errors='strict')

ファクトリ関数は、それぞれ基底クラスの StreamReaderStreamWriter が定義しているインタフェースを提供するオブジェクトを返さねばなりません。ストリーム codecs は内部状態を維持できます。

errors が取り得る値は

  • 'strict' エンコーディングエラーの際に例外を発生

  • 'replace' 奇形データを '?''\ufffd' 等の適切な文字で置換

  • 'ignore' 奇形データを無視し何も通知せずに処理を継続

  • 'xmlcharrefreplace' 適切な XML 文字参照で置換 (エンコーディングのみ))

  • 'backslashreplace' (バックスラッシュつきのエスケープシーケンス (エンコーディングのみ))

register_error() で定義されたその他のエラー処理名になります。

検索関数は、与えられたエンコーディングを見つけられなかった場合、 None を返さなければなりません。

codecs.lookup(encoding)

Python codec レジストリから codec 情報を探し、上で定義したような CodecInfo オブジェクトを返します。

エンコーディングの検索は、まずレジストリのキャッシュから行います。見つからなければ、登録されている検索関数のリストから探します。 CodecInfo オブジェクトが一つも見つからなければ LookupError を送出します。見つかったら、その CodecInfo オブジェクトはキャッシュに保存され、呼び出し側に返されます。

さまざまな codec へのアクセスを簡便化するために、このモジュールは以下のような関数を提供しています。これらの関数は、 codec の検索に lookup() を使います:

codecs.getencoder(encoding)

与えられたエンコーディングに対する codec を検索し、エンコーダ関数を返します。

エンコーディングが見つからなければ LookupError を送出します。

codecs.getdecoder(encoding)

与えられたエンコーディングに対する codec を検索し、デコーダ関数を返します。

エンコーディングが見つからなければ LookupError を送出します。

codecs.getincrementalencoder(encoding)

与えられたエンコーディングに対する codec を検索し、漸増的エンコーダクラスまたはファクトリ関数を返します。

エンコーディングが見つからないか、 codec が漸増的エンコーダをサポートしなければ LookupError を送出します。

バージョン 2.5 で追加.

codecs.getincrementaldecoder(encoding)

与えられたエンコーディングに対する codec を検索し、漸増的デコーダクラスまたはファクトリ関数を返します。

エンコーディングが見つからないか、 codec が漸増的デコーダをサポートしなければ LookupError を送出します。

バージョン 2.5 で追加.

codecs.getreader(encoding)

与えられたエンコーディングに対する codec を検索し、StreamReader クラスまたはファクトリ関数を返します。

エンコーディングが見つからなければ LookupError を送出します。

codecs.getwriter(encoding)

与えられたエンコーディングに対する codec を検索し、StreamWriter クラスまたはファクトリ関数を返します。

エンコーディングが見つからなければ LookupError を送出します。

codecs.register_error(name, error_handler)

エラー処理関数 error_handler を名前 name で登録します。エンコード中およびデコード中にエラーが送出された場合、 errors パラメタに name を指定していれば error_handler を呼び出すようになります。

エンコード時の error_handler はエラーの場所に関する情報の入った UnicodeEncodeError インスタンスとともに呼び出されます。エラー処理関数はこの例外を送出するか、別の例外を送出するか、または入力のエンコードができなかった部分の代替文字列とエンコードを再開する場所の指定が入ったタプルを返すかしなければなりません。最後の場合、エンコーダは代替文字列をエンコードし、元の入力中の指定位置からエンコードを再開します。位置を負の値にすると、入力文字列の末端からの相対位置として扱われます。境界の外側にある位置を返した場合には IndexError が送出されます。

デコードと翻訳は同様に働きますが、エラー処理関数に渡されるのが UnicodeDecodeErrorUnicodeTranslateError である点と、エラー処理関数の置換した内容が直接出力になる点が異なります。

codecs.lookup_error(name)

名前 name で登録済みのエラー処理関数を返します。

エラー処理関数が見つからなければ LookupError を送出します。

codecs.strict_errors(exception)

strict エラー処理の実装です: エンコード又はデコードエラーは各々 UnicodeError を送出します.

codecs.replace_errors(exception)

replace エラー処理の実装です: 奇形データは適切な文字列に置換されます。バイト文字列では '?' 、 Unicode 文字列では '\ufffd' に置換されます。

codecs.ignore_errors(exception)

ignore エラー処理の実装です: 奇形データは無視されエンコード又はデコードは何も通知せず、継続されます。

codecs.xmlcharrefreplace_errors(exception)

xmlcharrefreplace エラー処理の実装です(エンコードのみ): エンコードできなかった文字は適切な XML 文字参照に置き換えます。

codecs.backslashreplace_errors(exception)

backslashreplace エラー処理の実装です (エンコードのみ): エンコードできなかった文字はバックスラッシュつきのエスケープシーケンスに置き換えられます。

エンコードされたファイルやストリームの処理を簡便化するため、このモジュールは次のようなユーティリティ関数を定義しています:

codecs.open(filename, mode[, encoding[, errors[, buffering]]])

エンコードされたファイルを mode を使って開き、透過的なエンコード/デコードを提供するラップされたバージョンを返します。デフォルトのファイルモードは 'r' 、つまり、読み出しモードでファイルを開きます。

注釈

ラップされたバージョンは、該当する codec が定義している形式のオブジェクトだけを受け付けます。多くの組み込み codec では Unicode オブジェクトです。関数の戻り値も codec に依存し、通常は Unicode オブジェクトです。

注釈

非バイナリモードが指定されても、ファイルは常にバイナリモードで開かれます。これは、 8-bit の値を使うエンコーディングでデータが消失するのを防ぐためです。つまり、読み出しや書き込み時に、 `'\n' の自動変換はされないということです。

encoding にはファイルのエンコーディングを指定します。

エラーハンドリングのために errors を渡すことができます。これはデフォルトでは 'strict' で、エンコード時にエラーがあれば ValueError を送出します。

buffering は組み込み関数 open() の場合と同じ意味を持ちます。デフォルトでは行バッファリングです。

codecs.EncodedFile(file, input[, output[, errors]])

ラップしたファイルオブジェクトを返します。このオブジェクトは透過なエンコード変換を提供します。

ラップされたファイルに書かれた文字列は、 input に指定したエンコーディングに従って変換され、 output に指定したエンコーディングを使って string 型に変換され、元のファイルに書き込まれます。中間エンコーディングは指定された codecs に依存しますが、普通は Unicode です。

output が与えられなければ、input がデフォルトになります。

エラーハンドリングのために errors を渡すことができます。これはデフォルトでは 'strict' で、エンコード時にエラーがあれば ValueError を送出します。

codecs.iterencode(iterable, encoding[, errors])

漸増的エンコーダを使って、 iterable から供給される入力を反復的にエンコードします。この関数は generator です。 errors は (そして他のキーワード引数も同様に) 漸増的エンコーダにそのまま引き渡されます。

バージョン 2.5 で追加.

codecs.iterdecode(iterable, encoding[, errors])

漸増的デコーダを使って、 iterable から供給される入力を反復的にデコードします。この関数は generator です。 errors は (そして他のキーワード引数も同様に) 漸増的デコーダにそのまま引き渡されます。

バージョン 2.5 で追加.

このモジュールは以下のような定数も定義しています。プラットフォーム依存なファイルを読み書きするのに役立ちます:

codecs.BOM
codecs.BOM_BE
codecs.BOM_LE
codecs.BOM_UTF8
codecs.BOM_UTF16
codecs.BOM_UTF16_BE
codecs.BOM_UTF16_LE
codecs.BOM_UTF32
codecs.BOM_UTF32_BE
codecs.BOM_UTF32_LE

ここで定義された定数は、様々なエンコーディングの Unicode のバイトオーダマーカ (BOM) で、 UTF-16 と UTF-32 におけるデータストリームやファイルストリームのバイトオーダを指定したり、 UTF-8 における Unicode signature として使われます。 BOM_UTF16BOM_UTF16_BEBOM_UTF16_LE のいずれかで、プラットフォームのネイティブバイトオーダに依存します。 BOMBOM_UTF16 の別名です。同様に BOM_LEBOM_UTF16_LE の、 BOM_BEBOM_UTF16_BE の別名です。他は UTF-8 と UTF-32 エンコーディングの BOM を表します。

7.8.1. Codec 基底クラス

codecs モジュールでは、 codec のインタフェースを定義する一連の基底クラスを用意して、 Python 用 codec を簡単に自作できるようにしています。

Python で何らかの codec を使えるようにするには、状態なしエンコーダ、状態なしデコーダ、ストリームリーダ、ストリームライタの 4 つのインタフェースを定義しなければなりません。通常は、状態なしエンコーダとデコーダを再利用してストリームリーダとライタのファイル・プロトコルを実装します。

Codec クラスは、状態なしエンコーダ・デコーダのインタフェースを定義しています。

エラー処理の簡便化と標準化のため、encode() メソッドと decode() メソッドでは、 errors 文字列引数を指定した場合に別のエラー処理を行うような仕組みを実装してもかまいません。全ての標準 Python codec では以下の文字列が定義され、実装されています。

意味

'strict'

UnicodeError (または、そのサブクラス) を送出します -- デフォルトの動作です。

'ignore'

その文字を無視し、次の文字から変換を再開します。

'replace'

適当な文字で置換します -- Python の組み込み Unicode codec のデコード時には公式の U+FFFD REPLACEMENT CHARACTER を、エンコード時には '?' を使います。

'xmlcharrefreplace'

適切な XML 文字参照で置換します (エンコードのみ)。

'backslashreplace'

バックスラッシュつきのエスケープシーケンスで置換します (エンコードのみ)。

codecs がエラーハンドラとして受け入れる値は register_error() を使って追加できます。

7.8.1.1. Codec オブジェクト

Codec クラスは以下のメソッドを定義します。これらのメソッドは、内部状態を持たないエンコーダ/デコーダ関数のインタフェースを定義します:

Codec.encode(input[, errors])

オブジェクト input エンコードし、(出力オブジェクト, 消費した長さ) のタプルを返します。 codecs は Unicode 専用ではありませんが、 Unicode の文脈では、エンコーディングは Unicode オブジェクトを特定の文字集合エンコーディング(たとえば cp1252iso-8859-1) を使ってバイト文字列オブジェクトに変換します。

errors は適用するエラー処理を定義します。 'strict' 処理がデフォルトです。

このメソッドは Codec に内部状態を保存してはなりません。効率よくエンコードするために状態を保持しなければならないような codecs には StreamWriter を使ってください。

エンコーダは長さが 0 の入力を処理できなければなりません。この場合、空のオブジェクトを出力オブジェクトとして返さなければなりません。

Codec.decode(input[, errors])

オブジェクト input をデコードし、(出力オブジェクト, 消費した長さ) のタプルを返します。 Unicode の文脈では、デコードは特定の文字集合エンコーディングでエンコードされた文字列を Unicode オブジェクトに変換します。

inputbf_getreadbuf バッファスロットを提供するオブジェクトでなければなりません。バッファスロットを提供しているオブジェクトには Python 文字列オブジェクト、バッファオブジェクト、メモリマップファイルがあります。

errors は適用するエラー処理を定義します。 'strict' 処理がデフォルトです。

このメソッドは、 Codec インスタンスに内部状態を保存してはなりません。効率よくエンコード/デコードするために状態を保持しなければならないような codecs には StreamReader を使ってください。

デコーダは長さが 0 の入力を処理できなければなりません。この場合、空のオブジェクトを出力オブジェクトとして返さなければなりません。

IncrementalEncoder クラスおよび IncrementalDecoder クラスはそれぞれ漸増的エンコーディングおよびデコーディングのための基本的なインタフェースを提供します。エンコーディング/デコーディングは内部状態を持たないエンコーダ/デコーダを一度呼び出すことで行なわれるのではなく、漸増的エンコーダ/デコーダの encode()/decode() メソッドを複数回呼び出すことで行なわれます。漸増的エンコーダ/デコーダはメソッド呼び出しの間エンコーディング/デコーディング処理の進行を管理します。

encode()/decode() メソッド呼び出しの出力結果をまとめたものは、入力をひとまとめにして内部状態を持たないエンコーダ/デコーダでエンコード/デコードしたものと同じになります。

7.8.1.2. IncrementalEncoder オブジェクト

バージョン 2.5 で追加.

IncrementalEncoder クラスは入力を複数ステップでエンコードするのに使われます。全ての漸増的エンコーダが Python codec レジストリと互換性を持つために定義すべきメソッドとして、このクラスには以下のメソッドが定義されています。

class codecs.IncrementalEncoder([errors])

IncrementalEncoder インスタンスのコンストラクタ。

全ての漸増的エンコーダはこのコンストラクタインタフェースを提供しなければなりません。さらにキーワード引数を付け加えるのは構いませんが、Python codec レジストリで利用されるのはここで定義されているものだけです。

IncrementalEncodererrors キーワード引数を提供して異なったエラー取扱方法を実装することもできます。あらかじめ定義されているパラメータは以下の通りです:

  • 'strict' ValueError (またはそのサブクラス) を送出します。これがデフォルトです。

  • 'ignore' 一文字無視して次に進みます。

  • 'replace' 適当な代替文字で置き換えます。

  • 'xmlcharrefreplace' 適切な XML 文字参照に置き換えます。

  • 'backslashreplace' バックスラッシュ付きのエスケープシーケンスで置き換えます。

引数 errors は同名の属性に割り当てられます。属性に割り当てることで IncrementalEncoder オブジェクトが生きている間にエラー取扱戦略を違うものに切り替えることができるようになります。

errors 引数に許される値の集合は register_error() で拡張できます。

encode(object[, final])

object を(エンコーダの現在の状態を考慮に入れて)エンコードし、得られたエンコードされたオブジェクトを返します。 encode() 呼び出しがこれで最後という時には final は真でなければなりません(デフォルトは偽です)。

reset()

エンコーダを初期状態にリセットします。

7.8.1.3. IncrementalDecoder オブジェクト

IncrementalDecoder クラスは入力を複数ステップでデコードするのに使われます。全ての漸増的デコーダが Python codec レジストリと互換性を持つために定義すべきメソッドとして、このクラスには以下のメソッドが定義されています。

class codecs.IncrementalDecoder([errors])

IncrementalDecoder インスタンスのコンストラクタ。

全ての漸増的デコーダはこのコンストラクタインタフェースを提供しなければなりません。さらにキーワード引数を付け加えるのは構いませんが、Python codec レジストリで利用されるのはここで定義されているものだけです。

IncrementalDecodererrors キーワード引数を提供して異なったエラー取扱方法を実装することもできます。あらかじめ定義されているパラメータは以下の通りです:

  • 'strict' ValueError (またはそのサブクラス) を送出します。これがデフォルトです。

  • 'ignore' 一文字無視して次に進みます。

  • 'replace' 適切な置換文字で置換します。

引数 errors は同名の属性に割り当てられます。属性に割り当てることで IncrementalDecoder オブジェクトが生きている間にエラー取扱戦略を違うものに切り替えることができるようになります。

errors 引数に許される値の集合は register_error() で拡張できます。

decode(object[, final])

object を(デコーダの現在の状態を考慮に入れて)デコードし、得られたデコードされたオブジェクトを返します。 decode() 呼び出しがこれで最後という時には final は真でなければなりません(デフォルトは偽です)。もし final が真ならばデコーダは入力をデコードし切り全てのバッファをフラッシュしなければなりません。そうできない場合(たとえば入力の最後に不完全なバイト列があるから)、デコーダは内部状態を持たない場合と同じようにエラーの取り扱いを開始しなければなりません(例外を送出するかもしれません)。

reset()

デコーダを初期状態にリセットします。

StreamWriterStreamReader クラスは、新しいエンコーディングモジュールを、非常に簡単に実装するのに使用できる、一般的なインターフェイス提供します。実装例は encodings.utf_8 をご覧ください。

7.8.1.4. StreamWriter オブジェクト

StreamWriter クラスは Codec のサブクラスで、以下のメソッドを定義しています。全てのストリームライタは、 Python の codec レジストリとの互換性を保つために、これらのメソッドを定義する必要があります。

class codecs.StreamWriter(stream[, errors])

StreamWriter インスタンスのコンストラクタです。

全てのストリームライタはコンストラクタとしてこのインタフェースを提供しなければなりません。キーワード引数を追加しても構いませんが、Python の codec レジストリはここで定義されている引数だけを使います。

stream は、(バイナリで) 書き込み可能なファイル類似のオブジェクトでなくてはなりません。

StreamWriter は、 errors キーワード引数を受けて、異なったエラー処理の仕組みを実装しても構いません。定義済みのパラメタを以下に示します:

  • 'strict' ValueError (またはそのサブクラス) を送出します。これがデフォルトです。

  • 'ignore' 一文字無視して次に進みます。

  • 'replace' 適当な代替文字で置き換えます。

  • 'xmlcharrefreplace' 適切な XML 文字参照に置き換えます。

  • 'backslashreplace' バックスラッシュ付きのエスケープシーケンスで置き換えます。

errors 引数は、同名の属性に代入されます。この属性を変更すると、 StreamWriter オブジェクトが生きている間に、異なるエラー処理に変更できます。

errors 引数に許される値の集合は register_error() で拡張できます。

write(object)

object の内容をエンコードしてストリームに書き出します。

writelines(list)

文字列からなるリストを連結して、(必要に応じて write() を何度も使って) ストリームに書き出します。

reset()

状態保持に使われていた codec のバッファを強制的に出力してリセットします。

このメソッドが呼び出された場合、出力先データをきれいな状態にし、わざわざストリーム全体を再スキャンして状態を元に戻さなくても新しくデータを追加できるようにしなければなりません。

ここまでで挙げたメソッドの他にも、 StreamWriter では背後にあるストリームの他の全てのメソッドや属性を継承しなければなりません。

7.8.1.5. StreamReader オブジェクト

StreamReader クラスは Codec のサブクラスで、以下のメソッドを定義しています。全てのストリームリーダは、 Python の codec レジストリとの互換性を保つために、これらのメソッドを定義する必要があります。

class codecs.StreamReader(stream[, errors])

StreamReader インスタンスのコンストラクタです。

全てのストリームリーダはコンストラクタとしてこのインタフェースを提供しなければなりません。キーワード引数を追加しても構いませんが、Python の codec レジストリはここで定義されている引数だけを使います。

stream は、(バイナリで) 読み出し可能なファイル類似のオブジェクトでなくてはなりません。

StreamReader は、 errors キーワード引数を受けて、異なったエラー処理の仕組みを実装しても構いません。定義済みのパラメタを以下に示します:

  • 'strict' ValueError (またはそのサブクラス) を送出します。これがデフォルトです。

  • 'ignore' 一文字無視して次に進みます。

  • 'replace' 適切な置換文字で置換します。

errors 引数は、同名の属性に代入されます。この属性を変更すると、 StreamReader オブジェクトが生きている間に、異なるエラー処理に変更できます。

errors 引数に許される値の集合は register_error() で拡張できます。

read([size[, chars[, firstline]]])

ストリームからのデータをデコードし、デコード済のオブジェクトを返します。

chars はストリームから読み込む文字数です。 read()chars 以上の文字を返しませんが、それより少ない文字しか取得できない場合には chars 以下の文字を返します。

size は、デコードするためにストリームから読み込む、およその最大バイト数を意味します。デコーダはこの値を適切な値に変更できます。デフォルト値 -1 にすると可能な限りたくさんのデータを読み込みます。 size の目的は、巨大なファイルの一括デコードを防ぐことにあります。

firstline は、1行目さえ返せばその後の行でデコードエラーがあっても無視して十分だ、ということを示します。

このメソッドは貪欲な読み込み戦略を取るべきです。すなわち、エンコーディング定義と size の値が許す範囲で、できるだけ多くのデータを読むべきだということです。たとえば、ストリーム上にエンコーディングの終端や状態の目印があれば、それも読み込みます。

バージョン 2.4 で変更: chars 引数を追加しました.

バージョン 2.4.2 で変更: firstline 引数を追加しました.

readline([size[, keepends]])

入力ストリームから1行読み込み、デコード済みのデータを返します。

size が与えられた場合、ストリームの read() メソッドに size 引数として渡されます。

keepends が偽の場合には行末の改行が削除された行が返ります。

バージョン 2.4 で変更: keepends 引数を追加しました.

readlines([sizehint[, keepends]])

入力ストリームから全ての行を読み込み、行のリストとして返します。

keepends が真なら、改行は、codec のデコーダメソッドを使って実装され、リスト要素の中に含まれます。

sizehint が与えられた場合、ストリームの read() メソッドに size 引数として渡されます。

reset()

状態保持に使われた codec のバッファをリセットします。

ストリームの読み位置を再設定してはならないので注意してください。このメソッドはデコードの際にエラーから復帰できるようにするためのものです。

ここまでで挙げたメソッドの他にも、 StreamReader では背後にあるストリームの他の全てのメソッドや属性を継承しなければなりません。

次に挙げる2つの基底クラスは、利便性のために含まれています。codec レジストリは、これらを必要としませんが、実際のところ、あると有用なものでしょう。

7.8.1.6. StreamReaderWriter オブジェクト

StreamReaderWriter を使って、読み書き両方に使えるストリームをラップできます。

lookup() 関数が返すファクトリ関数を使って、インスタンスを生成するという設計です。

class codecs.StreamReaderWriter(stream, Reader, Writer, errors)

StreamReaderWriter インスタンスを生成します。 stream はファイル類似のオブジェクトです。 ReaderWriter は、それぞれ StreamReaderStreamWriter インタフェースを提供するファクトリ関数かファクトリクラスでなければなりません。エラー処理は、ストリームリーダとライタで定義したものと同じように行われます。

StreamReaderWriter インスタンスは、 StreamReader クラスと StreamWriter クラスを合わせたインタフェースを継承します。元になるストリームからは、他のメソッドや属性を継承します。

7.8.1.7. StreamRecoder オブジェクト

StreamRecoder はエンコーディングデータの、フロントエンド-バックエンドを観察する機能を提供します。異なるエンコーディング環境を扱うとき、便利な場合があります。

lookup() 関数が返すファクトリ関数を使って、インスタンスを生成するという設計です。

class codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors)

双方向変換を実装する StreamRecoder インスタンスを生成します。 encodedecode はフロントエンド (read() への入力と write() からの出力) を処理し、 ReaderWriter はバックエンド (ストリームに対する読み書き) を処理します。

これらのオブジェクトを使って、たとえば、 Latin-1 から UTF-8 、あるいは逆向きの変換を、透過に記録できます。

stream はファイル的オブジェクトでなくてはなりません。

encodedecodeCodec のインタフェースに忠実でなくてはならず、 ReaderWriter は、それぞれ StreamReaderStreamWriter のインタフェースを提供するオブジェクトのファクトリ関数かクラスでなくてはなりません。

encodedecode はフロントエンドの変換に必要で、 ReaderWriter はバックエンドの変換に必要です。中間のフォーマットはコデックの組み合わせによって決定されます。たとえば、 Unicode コデックは中間エンコーディングに Unicode を使います。

エラー処理はストリーム・リーダやライタで定義されている方法と同じように行われます。

StreamRecoder インスタンスは、 StreamReaderStreamWriter クラスを合わせたインタフェースを定義します。また、元のストリームのメソッドと属性も継承します。

7.8.2. エンコーディングと Unicode

Unicode 文字列は内部的にはコードポイントのシーケンスとして格納されます (正確に言えば Py_UNICODE 配列です)。 Python がどのようにコンパイルされたか (デフォルトである --enable-unicode=ucs2 かまたは --enable-unicode=ucs4 のどちらか) によって、 Py_UNICODE は16ビットまたは32ビットのデータ型です。 Unicode オブジェクトが CPU とメモリの外で使われることになると、 CPU のエンディアンやこれらの配列がバイト列としてどのように格納されるかが問題になってきます。 Unicode オブジェクトをバイト列に変換することをエンコーディングと呼び、バイト列から Unicode オブジェクトを再生することをデコーディングと呼びます。どのようにこの変換を行うかには多くの異なった方法があります (これらの方法のこともエンコーディングと言います) 。最も単純な方法はコードポイント 0--255 をバイト 0x0--0xff に写すことです。これは U+00FF より上のコードポイントを持つ Unicode オブジェクトはこの方法ではエンコードできないということを意味します (この方法を 'latin-1' とか 'iso-8859-1' と呼びます)。 unicode.encode() は次のような UnicodeEncodeError を送出することになります: UnicodeEncodeError: 'latin-1' codec can't encode character u'\u1234' in position 3: ordinal not in range(256)

他のエンコーディングの一群 (charmap エンコーディングと呼ばれます) がありますが、 Unicode コードポイントの別の部分集合とこれらがどのように 0x0--0xff のバイトに写されるかを選んだものです。これがどのように行なわれるかを知るには、単にたとえば encodings/cp1252.py (主に Windows で使われるエンコーディングです) を開いてみてください。256 文字のひとつの文字列定数がありどの文字がどのバイト値に写されるかを示しています。

これらのエンコーディングはすべて、 Unicode に定義された 1114112 のコードポイントのうちの 256 だけをエンコードすることができます。 Unicode のすべてのコードポイントを格納するための単純で直接的な方法は、各コードポイントを連続する4バイトとして格納することです。これには2つの可能性があります: ビッグエンディアンまたはリトルエンディアンの順にバイトを格納することです。これら2つのエンコーディングはそれぞれ UTF-32-BE および UTF-32-LE と呼ばれます。それらのデメリットは、例えばリトルエンディアンのマシン上で UTF-32-BE を使用すると、エンコードでもデコードでも常にバイト順を交換する必要があることです。UTF-32 はこの問題を回避します: バイト順は、常に自然なエンディアンに従います。しかし、これらのバイト順が異なるエンディアン性を持つ CPU によって読まれる場合、結局バイト順を交換しなければなりません。UTF-16 あるいは UTF-32 バイト列のエンディアン性を検出する目的で、いわゆる BOM (「バイト・オーダー・マーク」) があります。これは Unicode 文字 U+FEFF です。この文字はすべての UTF-16 あるいは UTF-32 バイト列の前に置くことができます。この文字のバイトが交換されたバージョン (0xFFFE) は、 Unicode テキストに現われてはならない不正な文字です。したがって、UTF-16 あるいは UTF-32 バイト列中の最初の文字が U+FFFE であるように見える場合、デコードの際にバイトを交換しなければなりません。不運にも文字 U+FEFFZERO WIDTH NO-BREAK SPACE として別の目的を持っていました: 幅を持たず、単語を分割することを許容しない文字。それは、例えばリガチャアルゴリズムにヒントを与えるために使用することができます。 Unicode 4.0 で、ZERO WIDTH NO-BREAK SPACE としての U+FEFF の使用は廃止予定になりました (この役割は U+2060 (WORD JOINER) によって引き継がれました)。しかしながら、 Unicode ソフトウェアは、依然として両方の役割の U+FEFF を扱うことができなければなりません: BOM として、エンコードされたバイトのメモリレイアウトを決定する手段であり、一旦バイト列が文字列にデコードされたならば消えます; ZERO WIDTH NO-BREAK SPACE として、他の任意の文字のようにデコードされる通常の文字です。

さらにもう一つ Unicode 文字全てをエンコードできるエンコーディングがあり、UTF-8 と呼ばれています。UTF-8 は8ビットエンコーディングで、したがって UTF-8 にはバイト順の問題はありません。UTF-8 バイト列の各バイトは二つのパートから成ります。二つはマーカ(上位数ビット)とペイロードです。マーカは0ビットから4ビットの 1 の列に 0 のビットが一つ続いたものです。Unicode 文字は次のようにエンコードされます (x はペイロードを表わし、連結されると一つの Unicode 文字を表わします):

範囲

エンコーディング

U-00000000 ... U-0000007F

0xxxxxxx

U-00000080 ... U-000007FF

110xxxxx 10xxxxxx

U-00000800 ... U-0000FFFF

1110xxxx 10xxxxxx 10xxxxxx

U-00010000 ... U-0010FFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Unicode 文字の最下位ビットとは最も右にある x のビットです。

UTF-8 は8ビットエンコーディングなので BOM は必要とせず、デコードされた Unicode 文字列中の U+FEFF は(たとえ最初の文字であったとしても) ZERO WIDTH NO-BREAK SPACE として扱われます。

外部からの情報無しには、Unicode 文字列のエンコーディングにどのエンコーディングが使われたのか信頼できる形で決定することは不可能です。どの charmap エンコーディングもどんなランダムなバイト列でもデコードできます。しかし UTF-8 ではそれは可能ではありません。任意のバイト列を許さないような構造を持っているからです。UTF-8 エンコーディングであることを検知する信頼性を向上させるために、Microsoft は Notepad プログラム用に UTF-8 の変種 (Python 2.5 では "utf-8-sig" と呼んでいます) を考案しました。Unicode 文字がファイルに書き込まれる前に UTF-8 でエンコードした BOM (バイト列では 0xef, 0xbb, 0xbf のように見えます) が書き込まれます。このようなバイト値で charmap エンコードされたファイルが始まることはほとんどあり得ない (たとえば iso-8859-1 では

LATIN SMALL LETTER I WITH DIAERESIS
RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
INVERTED QUESTION MARK

のようになる)ので、utf-8-sig エンコーディングがバイト列から正しく推測される確率を高めます。つまりここでは BOM はバイト列を生成する際のバイト順を決定できるように使われているのではなく、エンコーディングを推測する助けになる印として使われているのです。utf-8-sig codec はエンコーディングの際ファイルに最初の3文字として 0xef, 0xbb, 0xbf を書き込みます。デコーディングの際はファイルの先頭に現れたこれら3バイトはスキップします。UTF-8 では BOM の使用は推奨されておらず、一般的には避けるべきです。

7.8.3. 標準エンコーディング

Python には数多くの codec が組み込みで付属します。これらは C 言語の関数、対応付けを行うテーブルの両方で提供されています。以下のテーブルでは codec と、いくつかの良く知られている別名と、エンコーディングが使われる言語を列挙します。別名のリスト、言語のリストともしらみつぶしに網羅されているわけではありません。大文字と小文字、またはアンダースコアの代りにハイフンにしただけの綴りも有効な別名です; そのため、例えば 'utf-8''utf_8' codec の正当な別名です。

多くの文字セットは同じ言語をサポートしています。これらの文字セットは個々の文字 (例えば、EURO SIGN がサポートされているかどうか) や、文字のコード部分への割り付けが異なります。特に欧州言語では、典型的に以下の変種が存在します:

  • ISO 8859 コードセット

  • Microsoft Windows コードページで、8859 コード形式から導出されているが、制御文字を追加のグラフィック文字と置き換えたもの

  • IBM EBCDIC コードページ

  • ASCII 互換の IBM PC コードページ

Codec

別名

言語

ascii

646, us-ascii

英語

big5

big5-tw, csbig5

繁体字中国語

big5hkscs

big5-hkscs, hkscs

繁体字中国語

cp037

IBM037, IBM039

英語

cp424

EBCDIC-CP-HE, IBM424

ヘブライ語

cp437

437, IBM437

英語

cp500

EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500

西ヨーロッパ言語

cp720

アラビア語

cp737

ギリシャ語

cp775

IBM775

バルト沿岸国

cp850

850, IBM850

西ヨーロッパ言語

cp852

852, IBM852

中央および東ヨーロッパ

cp855

855, IBM855

ブルガリア、ベラルーシ、マケドニア、ロシア、セルビア

cp856

ヘブライ語

cp857

857, IBM857

トルコ語

cp858

858, IBM858

西ヨーロッパ言語

cp860

860, IBM860

ポルトガル語

cp861

861, CP-IS, IBM861

アイスランド語

cp862

862, IBM862

ヘブライ語

cp863

863, IBM863

カナダ

cp864

IBM864

アラビア語

cp865

865, IBM865

デンマーク、ノルウェー

cp866

866, IBM866

ロシア語

cp869

869, CP-GR, IBM869

ギリシャ語

cp874

タイ語

cp875

ギリシャ語

cp932

932, ms932, mskanji, ms-kanji

日本語

cp949

949, ms949, uhc

韓国語

cp950

950, ms950

繁体字中国語

cp1006

Urdu

cp1026

ibm1026

トルコ語

cp1140

ibm1140

西ヨーロッパ言語

cp1250

windows-1250

中央および東ヨーロッパ

cp1251

windows-1251

ブルガリア、ベラルーシ、マケドニア、ロシア、セルビア

cp1252

windows-1252

西ヨーロッパ言語

cp1253

windows-1253

ギリシャ語

cp1254

windows-1254

トルコ語

cp1255

windows-1255

ヘブライ語

cp1256

windows-1256

アラビア語

cp1257

windows-1257

バルト沿岸国

cp1258

windows-1258

ベトナム

euc_jp

eucjp, ujis, u-jis

日本語

euc_jis_2004

jisx0213, eucjis2004

日本語

euc_jisx0213

eucjisx0213

日本語

euc_kr

euckr, korean, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001

韓国語

gb2312

chinese, csiso58gb231280, euc- cn, euccn, eucgb2312-cn, gb2312-1980, gb2312-80, iso- ir-58

簡体字中国語

gbk

936, cp936, ms936

Unified Chinese

gb18030

gb18030-2000

Unified Chinese

hz

hzgb, hz-gb, hz-gb-2312

簡体字中国語

iso2022_jp

csiso2022jp, iso2022jp, iso-2022-jp

日本語

iso2022_jp_1

iso2022jp-1, iso-2022-jp-1

日本語

iso2022_jp_2

iso2022jp-2, iso-2022-jp-2

日本語, 韓国語, 簡体字中国語, 西欧, ギリシャ語

iso2022_jp_2004

iso2022jp-2004, iso-2022-jp-2004

日本語

iso2022_jp_3

iso2022jp-3, iso-2022-jp-3

日本語

iso2022_jp_ext

iso2022jp-ext, iso-2022-jp-ext

日本語

iso2022_kr

csiso2022kr, iso2022kr, iso-2022-kr

韓国語

latin_1

iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1

西ヨーロッパ

iso8859_2

iso-8859-2, latin2, L2

中央および東ヨーロッパ

iso8859_3

iso-8859-3, latin3, L3

エスペラント、マルタ

iso8859_4

iso-8859-4, latin4, L4

バルト沿岸国

iso8859_5

iso-8859-5, cyrillic

ブルガリア、ベラルーシ、マケドニア、ロシア、セルビア

iso8859_6

iso-8859-6, arabic

アラビア語

iso8859_7

iso-8859-7, greek, greek8

ギリシャ語

iso8859_8

iso-8859-8, hebrew

ヘブライ語

iso8859_9

iso-8859-9, latin5, L5

トルコ語

iso8859_10

iso-8859-10, latin6, L6

北欧語

iso8859_11

iso-8859-11, thai

タイ語

iso8859_13

iso-8859-13, latin7, L7

バルト沿岸国

iso8859_14

iso-8859-14, latin8, L8

ケルト語

iso8859_15

iso-8859-15, latin9, L9

西ヨーロッパ言語

iso8859_16

iso-8859-16, latin10, L10

南東ヨーロッパ

johab

cp1361, ms1361

韓国語

koi8_r

ロシア語

koi8_u

ウクライナ語

mac_cyrillic

maccyrillic

ブルガリア、ベラルーシ、マケドニア、ロシア、セルビア

mac_greek

macgreek

ギリシャ語

mac_iceland

maciceland

アイスランド語

mac_latin2

maclatin2, maccentraleurope

中央および東ヨーロッパ

mac_roman

macroman

西ヨーロッパ言語

mac_turkish

macturkish

トルコ語

ptcp154

csptcp154, pt154, cp154, cyrillic-asian

カザフ

shift_jis

csshiftjis, shiftjis, sjis, s_jis

日本語

shift_jis_2004

shiftjis2004, sjis_2004, sjis2004

日本語

shift_jisx0213

shiftjisx0213, sjisx0213, s_jisx0213

日本語

utf_32

U32, utf32

全ての言語

utf_32_be

UTF-32BE

全ての言語

utf_32_le

UTF-32LE

全ての言語

utf_16

U16, utf16

全ての言語

utf_16_be

UTF-16BE

全ての言語 (BMP のみ)

utf_16_le

UTF-16LE

全ての言語 (BMP のみ)

utf_7

U7, unicode-1-1-utf-7

全ての言語

utf_8

U8, UTF, utf8

全ての言語

utf_8_sig

全ての言語

7.8.4. Python 特有のエンコーディング

予め定義された codec のいくつかは Python 特有のものなので、それらの codec 名は Python の外では無意味なものとなります。以下に、想定されている入出力のタイプに基づいて、それらを表にしました(テキストエンコーディングは codec の最も一般的な使用例ですが、その根底にある codec 基盤は、ただのテキストエンコーディングというよりも、任意のデータの変換をサポートしていることに注意してください)。非対称的な codec については、その目的がエンコーディングの方向を説明しています。

以下の codec では Unicode から文字列へのエンコーディング 1 、文字列から Unicode へのデコーディング 2 を、Unicode テキストエンコーディング同様に提供しています。

Codec

別名

目的

idna

RFC 3490 の実装です。 encodings.idna も参照してください。

mbcs

dbcs

Windows のみ: 被演算子を ANSI コードページ (CP_ACP) に従ってエンコードします

palmos

PalmOS 3.5 のエンコーディングです

punycode

RFC 3492 を実装しています。

raw_unicode_escape

Python ソースコードにおける raw Unicode リテラルとして適切な文字列を生成します。

rot_13

rot13

被演算子のシーザー暗号 (Caesar-cypher) を返します

undefined

全ての変換に対して例外を送出します。バイト列と Unicode 文字列との間で coercion (強制型変換) をおこないたくない時にシステムエンコーディングとして使うことができます。

unicode_escape

Python ソースコードにおける Unicode リテラルとして適切な文字列を生成します。

unicode_internal

被演算子の内部表現を返します。

バージョン 2.3 で追加: idna, punycode エンコーディングの追加。

以下の codec では文字列から文字列へのエンコーディングとデコーディング 2 を提供しています。

Codec

別名

目的

エンコーダ/デコーダ

base64_codec

base64, base-64

被演算子をマルチラインの MIME base64 に変換します (結果は常に末尾の '\n' を含みます)

base64.encodestring(), base64.decodestring()

bz2_codec

bz2

被演算子をbz2を使って圧縮します

bz2.compress(), bz2.decompress()

hex_codec

hex

被演算子をバイトあたり 2 桁の 16 進数の表現に変換します

binascii.b2a_hex(), binascii.a2b_hex()

quopri_codec

quopri, quoted-printable, quotedprintable

被演算子を MIME quoted printable 形式に変換します

quotetabs=True を指定した quopri.encode(), quopri.decode()

string_escape

Python ソースコードにおける文字列リテラルとして適切な文字列を生成します。

uu_codec

uu

被演算子を uuencode を用いて変換します

uu.encode(), uu.decode()

zlib_codec

zip, zlib

被演算子を gzip を用いて圧縮します

zlib.compress(), zlib.decompress()

1

unicode オブジェクトを入力として受け容れる場所では str オブジェクトも許容されます。この場合デフォルトエンコーディングを使って暗黙に unicode に変換されます。この変換が失敗した場合はエンコード操作が UnicodeDecodeError を起こします。

2(1,2)

str オブジェクトを入力として受け容れる場所では unicode オブジェクトも許容されます。この場合デフォルトエンコーディングを使って暗黙に str に変換されます。この変換が失敗した場合はデコード操作が UnicodeEncodeError を起こします。

7.8.5. encodings.idna --- アプリケーションにおける国際化ドメイン名 (IDNA)

バージョン 2.3 で追加.

このモジュールでは RFC 3490 (アプリケーションにおける国際化ドメイン名、 IDNA: Internationalized Domain Names in Applications) および RFC 3492 (Nameprep: 国際化ドメイン名 (IDN) のための stringprep プロファイル) を実装しています。このモジュールは punycode エンコーディングおよび stringprep の上に構築されています。

これらの RFC はともに、非 ASCII 文字の入ったドメイン名をサポートするためのプロトコルを定義しています。 (www.Alliancefrançaise.nu のような) 非 ASCII 文字を含むドメイン名は、 ASCII と互換性のあるエンコーディング (ACE、 www.xn--alliancefranaise-npb.nu のような形式) に変換されます。ドメイン名の ACE 形式は、 DNS クエリ、 HTTP Host フィールドなどといった、プロトコル中で任意の文字を使えないような全ての局面で用いられます。この変換はアプリケーション内で行われます; 可能ならユーザからは不可視となります: アプリケーションは Unicode ドメインラベルをネットワークに載せる際に IDNA に、 ACE ドメインラベルをユーザに提供する前に Unicode に、それぞれ透過的に変換しなければなりません。

Python ではこの変換をいくつかの方法でサポートします: idna codec は Unicode と ACE 間の変換を行い、入力文字列を RFC 3490section 3.1 (1) で定義されている区切り文字に基づいてラベルに分解し、各ラベルを要求通りに ACE に変換します。逆に、入力のバイト文字列を . 区切り文字でラベルに分解し、 ACE ラベルを Unicode に変換します。さらに、 socket モジュールは Unicode ホスト名を ACE に透過的に変換するため、アプリケーションはホスト名を socket モジュールに渡す際にホスト名の変換に煩わされることがありません。その上で、ホスト名を関数パラメタとして持つ、 httplibftplib のようなモジュールでは Unicode ホスト名を受理します (httplib でもまた、 Host: フィールドにある IDNA ホスト名を、フィールド全体を送信する場合に透過的に送信します)。

(逆引きなどによって) ネットワーク越しにホスト名を受信する際、Unicode への自動変換は行われません: こうしたホスト名をユーザに提供したいアプリケーションでは、Unicode にデコードしてやる必要があります。

encodings.idna ではまた、 nameprep 手続きを実装しています。 nameprep はホスト名に対してある正規化を行って、国際化ドメイン名で大小文字を区別しないようにするとともに、類似の文字を一元化します。 nameprep 関数は必要なら直接使うこともできます。

encodings.idna.nameprep(label)

label を nameprep したバージョンを返します。現在の実装ではクエリ文字列を仮定しているので、AllowUnassigned は真です。

encodings.idna.ToASCII(label)

RFC 3490 仕様に従ってラベルを ASCIIに変換します。 UseSTD3ASCIIRules は偽であると仮定します。

encodings.idna.ToUnicode(label)

RFC 3490 仕様に従ってラベルを Unicode に変換します。

7.8.6. encodings.utf_8_sig --- BOM 印付き UTF-8

バージョン 2.5 で追加.

このモジュールは UTF-8 codec の変種を実装します。エンコーディング時は、UTF-8 でエンコードしたバイト列の前に UTF-8 でエンコードした BOM を追加します。これは内部状態を持つエンコーダで、この動作は (バイトストリームの最初の書き込み時に) 一度だけ行なわれます。デコーディング時は、データの最初に UTF-8 でエンコードされた BOM があれば、それをスキップします。