7.8. codecs — codec レジストリと基底クラス — Python 2.7ja1 documentation

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.7ja1 documentation »
- Python 標準ライブラリ »
- 7. 文字列処理 »

# 7.8. `codecs` — codec レジストリと基底クラス

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

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

`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')`

  ファクトリ関数は、基底クラスの `StreamWriter` や `StreamReader` が定義しているインタフェースを提供するオブジェクトを返さねばなりません。ストリーム 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)

  encoding に指定した codec を検索し、エンコーダ関数を返します。

  encoding が見つからなければ `LookupError` を送出します。

`codecs.` `getdecoder`(encoding)

  encoding に指定した codec を検索し、デコーダ関数を返します。

  encoding が見つからなければ `LookupError` を送出します。

`codecs.` `getincrementalencoder`(encoding)
  encoding に指定した codec を検索し、漸増的エンコーダクラス、また
    はファクトリ関数を返します。
  encoding が見つからない、もしくは codec が漸増的エンコーダをサポー
    トしないとき `LookupError` を送出します。

  バージョン 2.5 で追加.

`codecs.` `getincrementaldecoder`(encoding)
  encoding に指定した codec を検索し、漸増的デコーダクラス、または
    ファクトリ関数を返します。
  encoding が見つからない、もしくは codec が漸増的デコーダをサポー
    トしないとき `LookupError` を送出します。

  バージョン 2.5 で追加.

`codecs.` `getreader`(encoding)
  encoding に指定した codec を検索し、StreamReader クラス、またはファ
    クトリ関数を返します。

  encoding が見つからなければ `LookupError` を送出します。

`codecs.` `getwriter`(encoding)
  encoding に指定した codec を検索し、 StreamWriter クラス、または
    ファクトリ関数を返します。

  encoding が見つからなければ `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 では以下の文字列が定義され、実装されています。

Value | Meaning
--- | ---
`'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 には `StreamCodec` を使ってください。

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

`Codec.` `decode`(input[, errors])

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

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

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

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

  デコーダは長さが 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 の内容をエンコードしてストリームに書き出します。

  `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 が与えられた場合、ストリームにおける `readline()` の 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 に定義された65536(あるいは 1114111) あるコードポイント中256文字しかエンコードできません。全ての Unicode コードポイントを収める単純明快な方法は、それぞれのコードポイントを二つの引き続くバイトに収めるものです。二つの可能性があります。すなわちビッグエンディアンかリトルエンディアンか。これら二つのエンコーディングはそれぞれ UTF-16-BE あるいは UTF-16-LE と呼ばれます。欠点は、たとえば UTF-16-BE をリトルエンディアンの機械で使うときに、エンコーディングでもデコーディングでも常に二つのバイトを交換しなければならないことです。 UTF-16 はこの問題を解消します。バイトはいつでも自然なエンディアンに従います。これらのバイトが異なるエンディアンの CPU で読まれる時は、結局交換しない訳にはいきません。 UTF-16 のバイト列のエンディアンを検知できるようにするために、いわゆる BOM (“Byte Order Mark”) があります。 Unicode 文字で言うと `U+FEFF` です。この文字は全ての UTF-16 バイト列の先頭に付加されます。この文字のバイト位置を交換したもの (`0xFFFE`) は Unicode テキストに出現しないはずの違法な文字です。そこで、 UTF-16 バイト列の一文字目が `U+FFFE` に見えたなら、デコーディングの際にバイトを交換しなければなりません。不幸なことに、 Unicode 4.0 までは文字 `U+FEFF` には第二の目的 `ZERO WIDTH NO-BREAK SPACE` (幅を持たず単語が分割されるのを許さない文字) がありました。たとえばリガチャ(合字)アルゴリズムに対するヒントを与えるために使われることがあり得ます。 Unicode 4.0 になって `U+FEFF` の `ZERO WIDTH NO-BREAK SPACE` としての使用法は撤廃されました (`U+2060` (`WORD JOINER`) にこの役割を譲りました)。しかしながら、 Unicode ソフトウェアは依然として `U+FEFF` の二つの役割を扱えなければなりません。一つは BOM として、エンコードされたバイトの記憶装置上のレイアウトを決め、バイト列が Unicode 文字列にデコードされた暁には消え去るものという役割。もう一つは `ZERO WIDTH NO-BREAK SPACE` として、通常の文字と同じようにデコードされる文字という役割です。

さらにもう一つ Unicode 文字全てをエンコードできるエンコーディングがあり、 UTF-8 と呼ばれています。UTF-8 は8ビットエンコーディングで、したがって UTF-8 にはバイト順の問題はありません。UTF-8 バイト列の各バイトは二つのパートから成ります。二つはマーカ(上位数ビット)とペイロードです。マーカは0ビットから6ビットの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-001FFFFF` | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
`U-00200000` ... `U-03FFFFFF` | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
`U-04000000` ... `U-7FFFFFFF` | 1111110x 10xxxxxx 10xxxxxx 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バイトはスキップします。

## 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 | 簡体字中国語
gb18030 | gb18030-2000 | 簡体字中国語
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_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 only)
utf_16_le | UTF-16LE | 全ての言語 (BMP only)
utf_7 | U7, unicode-1-1-utf-7 | 全ての言語
utf_8 | U8, UTF, utf8 | 全ての言語
utf_8_sig |  | 全ての言語

codec のいくつかは Python 特有のものなので、それらの codec 名は Python の外では無意味なものとなります。これらの codec の中には Unicode 文字列からバイト文字列への変換を行わず、むしろ単一の引数をもつ全写像関数はエンコーディングとみなせるという Python codec の性質を利用したものもあります。

以下に列挙した codec では、”エンコード” 方向の結果は常にバイト文字列方向です。”デコード” 方向の結果はテーブル内の被演算子型として列挙されています。

Codec | 別名 | 被演算子の型 | 目的
--- | --- | --- | ---
base64_codec | base64, base-64 | byte string | 被演算子を MIME base64 に変換します。
bz2_codec | bz2 | byte string | 被演算子をbz2を使って圧縮します。
hex_codec | hex | byte string | 被演算子をバイトあたり 2 桁の 16 進数の表現に変換します。
idna |  | Unicode string | RFC 3490 の実装です。 `encodings.idna` も参照してください。
mbcs | dbcs | Unicode string | Windows のみ: 被演算子を ANSI コードページ (CP_ACP) に従ってエンコードします。
palmos |  | Unicode string | PalmOS 3.5 のエンコーディングです。
punycode |  | Unicode string | RFC 3492 を実装しています。
quopri_codec | quopri, quoted-printable, quotedprintable | byte string | 被演算子を MIME quoted printable 形式に変換します。
raw_unicode_escape |  | Unicode string | Python ソースコードにおける raw Unicode リテラルとして適切な文字列を生成します。
rot_13 | rot13 | Unicode string | 被演算子のシーザー暗号 (Caesar- cypher) を返します。
string_escape |  | byte string | Python ソースコードにおける文字列リテラルとして適切な文字列を生成します。
undefined |  | any | 全ての変換に対して例外を送出します。バイト列と Unicode 文字列との間で coercion (強制型変換) をおこないたくない時にシステムエンコーディングとして使うことができます。
unicode_escape |  | Unicode string | Python ソースコードにおける Unicode リテラルとして適切な文字列を生成します。
unicode_internal |  | Unicode string | 被演算子の内部表現を返します。
uu_codec | uu | byte string | 被演算子を uuencode を用いて変換します。
zlib_codec | zip, zlib | byte string | 被演算子を gzip を用いて圧縮します。

バージョン 2.3 で追加: The `idna` and `punycode` encodings.

## 7.8.4. `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` は真です。

`encodings.idna.` `ToASCII`(label)

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

`encodings.idna.` `ToUnicode`(label)

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

## 7.8.5. `encodings.utf_8_sig` — BOM 印付き UTF-8

バージョン 2.5 で追加.

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

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.7ja1 documentation »
- Python 標準ライブラリ »
- 7. 文字列処理 »