## 3.14.1 他の Python モジュールとの関係

`pickle` モジュールには `cPickle` と呼ばれる 最適化のなされた親類モジュールがあります。名前が示すように、 `cPickle` は C で書かれており、このため `pickle` より 1000 倍くらいまで高速になる可能性があります。しかしながら `cPickle` では `Pickler()` および `Unpickler()` クラスのサブクラス化をサポートしていません。 これは `cPickle` では、これらは関数であってクラスでは ないからです。ほとんどのアプリケーションではこの機能は 不要であり、`cPickle` の持つ高いパフォーマンスの 恩恵を受けることができます。その他の点では、二つのモジュールに おけるインタフェースはほとんど同じです; このマニュアルでは 共通のインタフェースを記述しており、必要に応じてモジュール間 の相違について指摘します。以下の議論では、`pickle` と `cPickle` の総称として ``pickle'' という用語を使う ことにします。

これら二つのモジュールが生成するデータストリームは相互交換 できることが保証されています。

Python には `marshal` と呼ばれるより原始的な直列化モジュール がありますが、一般的に Python オブジェクトを直列化する方法としては `pickle` を選ぶべきです。`marshal` は基本的に .pyc ファイルをサポートするために存在しています。

`pickle` モジュールはいくつかの点で `marshal` と明確に異なります:

- `pickle` モジュールでは、同じオブジェクトが再度直列化 されることのないよう、すでに直列化されたオブジェクトについて追跡 情報を保持します。`marshal` はこれを行いません。

  この機能は再帰的オブジェクトと共有オブジェクトの両方に重要な 関わりをもっています。再帰的オブジェクトとは自分自身に対する 参照を持っているオブジェクトです。再帰的オブジェクトは marshal で扱うことができず、実際、再帰的オブジェクトを marshal 化しようと すると Python インタプリタをクラッシュさせてしまいます。 共有オブジェクトは、直列化しようとするオブジェクト階層の異なる 複数の場所で同じオブジェクトに対する参照が存在する場合に生じます。 共有オブジェクトを共有のままにしておくことは、変更可能なオブジェクト の場合には非常に重要です。

- `marshal` はユーザ定義クラスやそのインスタンスを 直列化するために使うことができません。`pickle` は クラスインスタンスを透過的に保存したり復元したりすることができますが、 クラス定義をインポートすることが可能で、かつオブジェクトが保存 された際と同じモジュールで定義されていなければなりません。

- `marshal` の直列化フォーマットは Python の異なる バージョンで可搬性があることを保証していません。`marshal` の本来の仕事は .pyc ファイルのサポートなので、Python を実装する人々には、必要に応じて直列化フォーマットを以前の バージョンと互換性のないものに変更する権限が残されています。 `pickle` 直列化フォーマットには、全ての Python リリース 間で以前のバージョンとの互換性が保証されています。

`pickle` モジュールは誤りを含む、あるいは悪意を持って 構築されたデータに対して安全にはされていません。信用できない、 あるいは認証されていないデータ源から受信したデータを逆 pickle 化 しないでください。

直列化は永続化 (persisitence) よりも原始的な概念です; `pickle` はファイルオブジェクトを読み書きしますが、永続化 されたオブジェクトの名前付け問題や、(より複雑な) オブジェクトに 対する競合アクセスの問題を扱いません。`pickle` モジュール は複雑なオブジェクトをバイトストリームに変換することができ、 バイトストリームを変換前と同じ内部構造をオブジェクトに変換する ことができます。このバイトストリームの最も明白な用途は ファイルへの書き込みですが、その他にもネットワークを介して送信 したり、データベースに記録したりすることができます。 モジュール `shelve` はオブジェクトを DBM 形式の データベースファイル上で pickle 化したり unpickle 化したりする ための単純なインタフェースを提供しています。