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ストリームリーダクラスまたはファクトリ関数。
種々の関数やクラスが以下の引数をとります:
encode と decode: これらの引数は、 Codec インスタンスの
encode()とdecode()と同じインタフェースを持つ関数、またはメソッドでなければなりません (Codec Interface 参照) 。これらの関数・メソッドは内部状態を持たずに動作する (stateless mode) と想定されています。incrementalencoder と incrementaldecoder: これらは以下のインタフェースを持つファクトリ関数でなければなりません:
factory(errors='strict')ファクトリ関数は、それぞれ基底クラスの
IncrementalEncoderやIncrementalDecoderが定義しているインタフェースを提供するオブジェクトを返さなければなりません。漸増的 codecs は内部状態を維持できます。streamreader と streamwriter: これらの引数は、次のようなインタフェースを持つファクトリ関数でなければなりません:
factory(stream, errors='strict')ファクトリ関数は、それぞれ基底クラスの
StreamReaderやStreamWriterが定義しているインタフェースを提供するオブジェクトを返さねばなりません。ストリーム 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が送出されます。デコードと翻訳は同様に働きますが、エラー処理関数に渡されるのが
UnicodeDecodeErrorかUnicodeTranslateErrorである点と、エラー処理関数の置換した内容が直接出力になる点が異なります。
-
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_UTF16はBOM_UTF16_BEとBOM_UTF16_LEのいずれかで、プラットフォームのネイティブバイトオーダに依存します。BOMはBOM_UTF16の別名です。同様にBOM_LEはBOM_UTF16_LEの、BOM_BEはBOM_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 オブジェクトを特定の文字集合エンコーディング(たとえば
cp1252やiso-8859-1) を使ってバイト文字列オブジェクトに変換します。errors は適用するエラー処理を定義します。
'strict'処理がデフォルトです。このメソッドは
Codecに内部状態を保存してはなりません。効率よくエンコードするために状態を保持しなければならないような codecs にはStreamWriterを使ってください。エンコーダは長さが 0 の入力を処理できなければなりません。この場合、空のオブジェクトを出力オブジェクトとして返さなければなりません。
-
Codec.decode(input[, errors])¶ オブジェクト input をデコードし、(出力オブジェクト, 消費した長さ) のタプルを返します。 Unicode の文脈では、デコードは特定の文字集合エンコーディングでエンコードされた文字列を Unicode オブジェクトに変換します。
input は
bf_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 レジストリで利用されるのはここで定義されているものだけです。
IncrementalEncoderは errors キーワード引数を提供して異なったエラー取扱方法を実装することもできます。あらかじめ定義されているパラメータは以下の通りです:'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 レジストリで利用されるのはここで定義されているものだけです。
IncrementalDecoderは errors キーワード引数を提供して異なったエラー取扱方法を実装することもできます。あらかじめ定義されているパラメータは以下の通りです:'strict'ValueError(またはそのサブクラス) を送出します。これがデフォルトです。'ignore'一文字無視して次に進みます。'replace'適切な置換文字で置換します。
引数 errors は同名の属性に割り当てられます。属性に割り当てることで
IncrementalDecoderオブジェクトが生きている間にエラー取扱戦略を違うものに切り替えることができるようになります。errors 引数に許される値の集合は
register_error()で拡張できます。-
decode(object[, final])¶ object を(デコーダの現在の状態を考慮に入れて)デコードし、得られたデコードされたオブジェクトを返します。
decode()呼び出しがこれで最後という時には final は真でなければなりません(デフォルトは偽です)。もし final が真ならばデコーダは入力をデコードし切り全てのバッファをフラッシュしなければなりません。そうできない場合(たとえば入力の最後に不完全なバイト列があるから)、デコーダは内部状態を持たない場合と同じようにエラーの取り扱いを開始しなければなりません(例外を送出するかもしれません)。
-
reset()¶ デコーダを初期状態にリセットします。
StreamWriter と StreamReader クラスは、新しいエンコーディングモジュールを、非常に簡単に実装するのに使用できる、一般的なインターフェイス提供します。実装例は 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 の内容をエンコードしてストリームに書き出します。
-
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 はファイル類似のオブジェクトです。 Reader と Writer は、それぞれStreamReaderとStreamWriterインタフェースを提供するファクトリ関数かファクトリクラスでなければなりません。エラー処理は、ストリームリーダとライタで定義したものと同じように行われます。
StreamReaderWriter インスタンスは、 StreamReader クラスと StreamWriter クラスを合わせたインタフェースを継承します。元になるストリームからは、他のメソッドや属性を継承します。
7.8.1.7. StreamRecoder オブジェクト¶
StreamRecoder はエンコーディングデータの、フロントエンド-バックエンドを観察する機能を提供します。異なるエンコーディング環境を扱うとき、便利な場合があります。
lookup() 関数が返すファクトリ関数を使って、インスタンスを生成するという設計です。
-
class
codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors)¶ 双方向変換を実装する
StreamRecoderインスタンスを生成します。 encode と decode はフロントエンド (read()への入力とwrite()からの出力) を処理し、 Reader と Writer はバックエンド (ストリームに対する読み書き) を処理します。これらのオブジェクトを使って、たとえば、 Latin-1 から UTF-8 、あるいは逆向きの変換を、透過に記録できます。
stream はファイル的オブジェクトでなくてはなりません。
encode と decode は
Codecのインタフェースに忠実でなくてはならず、 Reader と Writer は、それぞれStreamReaderとStreamWriterのインタフェースを提供するオブジェクトのファクトリ関数かクラスでなくてはなりません。encode と decode はフロントエンドの変換に必要で、 Reader と Writer はバックエンドの変換に必要です。中間のフォーマットはコデックの組み合わせによって決定されます。たとえば、 Unicode コデックは中間エンコーディングに Unicode を使います。
エラー処理はストリーム・リーダやライタで定義されている方法と同じように行われます。
StreamRecoder インスタンスは、 StreamReader と StreamWriter クラスを合わせたインタフェースを定義します。また、元のストリームのメソッドと属性も継承します。
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+FEFF は ZERO 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 DIAERESISRIGHT-POINTING DOUBLE ANGLE QUOTATION MARKINVERTED 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 3490 の section 3.1 (1) で定義されている区切り文字に基づいてラベルに分解し、各ラベルを要求通りに ACE に変換します。逆に、入力のバイト文字列を . 区切り文字でラベルに分解し、 ACE ラベルを Unicode に変換します。さらに、 socket モジュールは Unicode ホスト名を ACE に透過的に変換するため、アプリケーションはホスト名を socket モジュールに渡す際にホスト名の変換に煩わされることがありません。その上で、ホスト名を関数パラメタとして持つ、 httplib や ftplib のようなモジュールでは Unicode ホスト名を受理します (httplib でもまた、 Host: フィールドにある IDNA ホスト名を、フィールド全体を送信する場合に透過的に送信します)。
(逆引きなどによって) ネットワーク越しにホスト名を受信する際、Unicode への自動変換は行われません: こうしたホスト名をユーザに提供したいアプリケーションでは、Unicode にデコードしてやる必要があります。
encodings.idna ではまた、 nameprep 手続きを実装しています。 nameprep はホスト名に対してある正規化を行って、国際化ドメイン名で大小文字を区別しないようにするとともに、類似の文字を一元化します。 nameprep 関数は必要なら直接使うこともできます。
-
encodings.idna.nameprep(label)¶ label を nameprep したバージョンを返します。現在の実装ではクエリ文字列を仮定しているので、
AllowUnassignedは真です。
7.8.6. encodings.utf_8_sig — BOM 印付き UTF-8¶
バージョン 2.5 で追加.
このモジュールは UTF-8 codec の変種を実装します。エンコーディング時は、UTF-8 でエンコードしたバイト列の前に UTF-8 でエンコードした BOM を追加します。これは内部状態を持つエンコーダで、この動作は (バイトストリームの最初の書き込み時に) 一度だけ行なわれます。デコーディング時は、データの最初に UTF-8 でエンコードされた BOM があれば、それをスキップします。
