"pickle" --- Python オブジェクトの直列化
****************************************

**ソースコード:** Lib/pickle.py

======================================================================

"pickle" モジュールは Python オブジェクトの直列化および直列化されたオ
ブジェクトの復元のためのバイナリプロトコルを実装しています。*"Pickle
化"* は Python オブジェクト階層をバイトストリームに変換する処理、*"非
pickle 化"* は (*バイナリファイル* または *バイトライクオブジェクト*
から) バイトストリームをオブジェクト階層に復元する処理を意味します。
pickle 化 (および非 pickle 化) は "直列化 (serialization)"、"整列化
(marshalling)"、あるいは [1] "平坦化 (flattening)" とも呼ばれますが、
混乱を避けるため、ここでは "Pickle 化"、"非 pickle 化" で統一します。

警告:

  "pickle" モジュールは **安全ではありません** 。信頼できるデータのみ
  を非 pickle 化してください。**非 pickle 化の過程で任意のコードを実行
  する** ような、悪意ある pickle オブジェクトを生成することが可能です
  。信頼できない提供元からのデータや、改竄された可能性のあるデータの非
  pickle 化は絶対に行わないでください。データが改竄されていないことを
  保証したい場合は、 "hmac" による鍵付きハッシュ化を検討してください。
  信頼できないデータを処理する場合 "json" のようなより安全な直列化形式
  の方が適切でしょう。 json との比較 を参照してください。


他の Python モジュールとの関係
==============================


"marshal" との比較
------------------

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

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

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

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

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

* "marshal" の直列化形式は Python のバージョン間での移植性を保証してい
  ません。  ".pyc" ファイルをサポートすることが主な役割であるため、
  Python 開発者は必要があれば直列化形式に非互換な変更を加える権利を有
  しています。 いっぽう "pickle" の直列化形式は、互換性のあるプロトコ
  ルを選ぶという条件のもとで Python リリース間の後方互換性が保証されま
  す。また処理すべきデータが Python 2 と Python 3 の間で非互換な型を含
  む場合も、 pickle 化および非 pickle 化のコードはそのような互換性を破
  る言語の境界を適切に取り扱います。


"json" との比較
---------------

pickle プロトコルと JSON (JavaScript Object Notation) との基本的な違い
は以下のとおりです:

* JSON はテキストの直列化フォーマット (大抵の場合 "utf-8" にエンコード
  されますが、その出力は Unicode 文字列です) で、pickle はバイナリの直
  列化フォーマットです;

* JSON は人間が読める形式ですが、pickle はそうではありません;

* JSON は相互運用可能で Python 以外でも広く使用されていますが、pickle
  は Python 固有です;

* JSON は、デフォルトでは Python の組み込み型の一部しか表現することが
  できず、カスタムクラスに対しても行えません; pickle は極めて多くの
  Python 組み込み型を表現できます (その多くは賢い Python 内省機構によ
  って自動的に行われます; 複雑なケースでは 固有のオブジェクト API によ
  って対応できます)。

* pickleとは異なり、信頼できないJSONを復元するだけでは、任意のコードを
  実行できる脆弱性は発生しません。

参考: "json" モジュール: JSON への直列化および復元を行うための標準ライブラ
    リモジュール。


データストリームの形式
======================

"pickle" によって使用されるデータフォーマットは Python 固有です。これ
は、JSON や XDR のような外部標準によって (例えばポインター共有を表わす
ことができないといったような) 制限を受けることがないという利点がありま
す; ただし、これは非 Python プログラムが pickle された Python オブジェ
クトを再構成することができないということも意味します。

デフォルトでは、"pickle" データフォーマットは比較的コンパクトなバイナ
リ表現を使用します。サイズの抑制目的の最適化が必要なら、pickle された
データを効率的に 圧縮する ことができます。

"pickletools" モジュールには "pickle" によって生成されたデータストリー
ムを解析するためのツールが含まれます。"pickletools" のソースコードには
、pickle プロトコルで使用される命令コードに関する詳細なコメントがあり
ます。

現在 pickle 化には 6 種類のプロトコルを使用できます。より高いプロトコ
ルを使用するほど、作成された pickle を読み込むためにより高い Python の
バージョンが必要になります。

* プロトコルバージョン 0 はオリジナルの「人間に判読可能な」プロトコル
  で、Python の初期のバージョンとの後方互換性を持ちます。

* プロトコルバージョン 1 は旧形式のバイナリフォーマットで、これも
  Python の初期バージョンと互換性があります。

* プロトコルバージョン 2 は Python 2.3 で導入されました。このバージョ
  ンでは *新方式のクラス* のより効率的な pickle 化を提供しました。プロ
  トコル 2 による改良に関する情報は **PEP 307** を参照してください。

* プロトコルバージョン 3 は Python 3 で追加されました。 "bytes" オブジ
  ェクトを明示的にサポートしており、 Python 2.x で unpickle することは
  できません。これは Python 3.0から3.7のデフォルトプロトコルでした。

* プロトコルバージョン 4 は Python 3.4 で追加されました。このバージョ
  ンでは巨大なオブジェクトのサポート、より多くの種類のオブジェクトの
  pickle 化、および一部のデータ形式の最適化が行われました。これは
  Python 3.8からのデフォルトプロトコルです。プロトコル 4 による改良に
  関する情報は **PEP 3154** を参照してください。

* プロトコルバージョン 5 は Python 3.8 で追加されました。このバージョ
  ンでは帯域外データのサポートが追加され、また帯域内データに対するパフ
  ォーマンスが向上します。プロトコルバージョン 5 によってもたらされる
  改善についての情報は **PEP 574** を参照してください。

注釈:

  直列化は永続性より原始的な概念です。 "pickle" はファイルオブジェクト
  の読み書きを行いますが、永続オブジェクトの命名に関する問題にも、(さ
  らに困難な) 永続オブジェクトへの並列アクセスに関する問題にも対応しま
  せん。"pickle" モジュールは複雑なオブジェクトをバイトストリームに変
  換し、バイトストリームから同じ内部構造のオブジェクトに復元することが
  できます。これらのバイトストリームはファイルに出力されることが多いで
  しょうが、ネットワークを介して送信したり、データベースに格納すること
  もありえます。"shelve" モジュールは、オブジェクトを DBM 方式のデータ
  ベースファイル上で pickle 化および非 pickle 化するシンプルなインター
  フェースを提供します。


モジュールインターフェース
==========================

オブジェクト階層を直列化するには、"dumps()" 関数を呼ぶだけです。同様に
、データストリームを復元するには、"loads()" 関数を呼びます。しかし、直
列化および復元に対してより多くのコントロールを行いたい場合、それぞれ
"Pickler" または "Unpickler" オブジェクトを作成することができます。

"pickle" モジュールは以下の定数を提供しています:

pickle.HIGHEST_PROTOCOL

   利用可能なうち最も高い プロトコルバージョン (整数)。この値は
   *protocol* 値として関数 "dump()"  および "dumps()" と、"Pickler" コ
   ンストラクターに渡すことができます。

pickle.DEFAULT_PROTOCOL

   pickle化に使われるデフォルトの プロトコルバージョン (整数)。
   *HIGHEST_PROTOCOL* よりも小さい場合があります。現在のデフォルトプロ
   トコルは4です。このプロトコルはPython3.4で初めて導入され、その前の
   バージョンとは互換性がありません。

   バージョン 3.0 で変更: デフォルトプロトコルは 3 です。

   バージョン 3.8 で変更: デフォルトプロトコルは 4 です。

この pickle 化の手続きを便利にするために、 "pickle" モジュールでは以下
の関数を提供しています:

pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)

   オブジェクト *obj* を pickle 化し、すでにオープンしている *ファイル
   オブジェクト* *file* に書き込みます。"Pickler(file,
   protocol).dump(obj)" と等価です。

   引数 *file*, *protocol*, *fix_imports* および *buffer_callback* は
   "Pickler" のコンストラクタと同じ意味になります。

   バージョン 3.8 で変更: *buffer_callback* 引数が追加されました。

pickle.dumps(obj, protocol=None, *, fix_imports=True, buffer_callback=None)

   ファイルに書く代わりに、"bytes" オブジェクトとしてオブジェクト
   *obj* の pickle 表現を返します。

   引数 *protocol*, *fix_imports* および *buffer_callback* は
   "Pickler" のコンストラクタと同じ意味になります。

   バージョン 3.8 で変更: *buffer_callback* 引数が追加されました。

pickle.load(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

   あるオブジェクトの pickle 化表現を、オープンしている *ファイルオブ
   ジェクト* *file* から読み込み、その中で指定されているオブジェクト階
   層に再構成して返します。これは "Unpickler(file).load()" と等価です
   。

   pickle のプロトコルバージョンは自動的に検出されます。したがって
   protocol 引数は必要ありません。pickle 化オブジェクト表現より後のバ
   イト列は無視されます。

   引数 *file*, *fix_imports*, *encoding*, *errors*, *strict* および
   *buffers* は "Unpickler" のコンストラクタと同じ意味になります。

   バージョン 3.8 で変更: *buffers* 引数が追加されました。

pickle.loads(data, /, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

   オブジェクトのピックル化表現 *data* から再構成されたオブジェクト階
   層を返します。 *data* は バイトライクオブジェクト (*bytes-like
   object*) でなければなりません。

   pickle のプロトコルバージョンは自動的に検出されます。したがって
   protocol 引数は必要ありません。pickle 化オブジェクト表現より後のバ
   イト列は無視されます。

   引数 *fix_imports*, *encoding*, *errors*, *strict* および *buffers*
   は "Unpickler" のコンストラクタと同じ意味になります。

   バージョン 3.8 で変更: *buffers* 引数が追加されました。

"pickle" モジュールでは 3 つの例外を定義しています:

exception pickle.PickleError

   他の pickle 化例外の共通基底クラス。"Exception" を継承しています。

exception pickle.PicklingError

   "Pickler" が pickle 化不可能なオブジェクトに遭遇したときに送出され
   るエラー。"PickleError" を継承しています。

   どんな種類のオブジェクトが pickle 化できるのか確認するには pickle
   化、非 pickle 化できるもの を参照してください。

exception pickle.UnpicklingError

   データ破損やセキュリティ違反のような、オブジェクトを非 pickle 化す
   るのに問題がある場合に送出されるエラー。"PickleError" を継承します
   。

   非 picke 化の最中に他の例外が送出されることもあるので注意してくださ
   い。これには AttributeError, EOFError, ImportError, IndexError が含
   まれます (ただし必ずしもこれらに限定されません)。

"pickle" モジュールでは、3 つのクラス "Pickler", "Unpickler" および
"PickleBuffer" を提供しています:

class pickle.Pickler(file, protocol=None, *, fix_imports=True, buffer_callback=None)

   pickle 化されたオブジェクトのデータストリームを書き込むためのバイナ
   リファイルを引数にとります。

   任意の引数 *protocol* は、整数で、pickle 化で使用するプロトコルを指
   定します; サポートされているプロトコルは 0 から "HIGHEST_PROTOCOL"
   までになります。指定されない場合、"DEFAULT_PROTOCOL" が使用されます
   。負数が与えられた場合、"HIGHEST_PROTOCOL" が使用されます。

   引数 *file* は、1 バイトの引数一つを受け付ける write() メソッドを持
   たなければなりません。すなわち、*file* には、バイナリの書き込み用に
   オープンされたファイルオブジェクト、"io.BytesIO" オブジェクト、この
   インターフェースに適合するその他のカスタムオブジェクトをとることが
   できます。

   *fix_imports* が真であり、かつ、*protocol* が 3 未満の場合、pickle
   は新しい Python 3 の名前と Python 2 で使用されていた古いモジュール
   名との対応付けを試みるので、pickle データストリームは Python 2 でも
   読み込み可能です。

   *buffer_callback* が None (デフォルト) の場合、バッファビューはスト
   リームの一部として*file* 中に直列化されます。

   *buffer_callback* が None でない場合、バッファビューを引数として何
   度でも呼び出すことができる関数です。コールバック関数が偽値 (None な
   ど) を返すと、与えられたバッファは アウトオブバウンド管理 (out-of-
   band) となります; そうでない場合はインバンドで、すなわち pickle ス
   トリーム内で、直列化されます。

   *buffer_callback* が None でなく、かつ *protocol* が None または 5
   より小さい場合はエラーとなります。

   バージョン 3.8 で変更: *buffer_callback* 引数が追加されました。

   dump(obj)

      *obj* の pickle 化表現を、コンストラクターで与えられた、すでにオ
      ープンしているファイルオブジェクトに書き込みます。

   persistent_id(obj)

      デフォルトでは何もしません。このメソッドはサブクラスがオーバーラ
      イドできるように存在します。

      "persistent_id()" が "None" を返す場合、通常通り *obj* が pickle
      化されます。それ以外の値を返した場合、"Pickler" がその値を *obj*
      のために永続的な ID として出力するようになります。この永続的な
      ID の意味は "Unpickler.persistent_load()" によって定義されていま
      す。"persistent_id()" によって返された値自身は永続的な ID を持つ
      ことができないことに注意してください。

      詳細および使用例については 外部オブジェクトの永続化 を参照してく
      ださい。

   dispatch_table

      pickler オブジェクトのディスパッチテーブルは "copyreg.pickle()"
      を使用して宣言できる種類の *reduction functions* のレジストリで
      す。これはキーがクラスでその値が減少関数のマッピング型オブジェク
      トです。減少関数は関連するクラスの引数を 1 個とり、
      "__reduce__()" メソッドと同じインターフェースでなければなりませ
      ん。

      デフォルトでは、pickler オブジェクトは "dispatch_table" 属性を持
      たず、代わりに "copyreg" モジュールによって管理されるグローバル
      なディスパッチテーブルを使用します。しかし、特定の pickler オブ
      ジェクトによる pickle 化をカスタマイズするために
      "dispatch_table" 属性に dict-like オブジェクトを設定することがで
      きます。あるいは、"Pickler" のサブクラスが "dispatch_table" 属性
      を持てば、そのクラスのインスタンスに対するデフォルトのディスパッ
      チテーブルとして使用されます。

      使用例については ディスパッチテーブル を参照してください。

      バージョン 3.3 で追加.

   reducer_override(obj)

      "Pickler" のサブクラスで定義可能な特殊なリデューサ (reducer) で
      す。このメソッドは "dispatch_table" 内のいかなるリデューサよりも
      優先されます。このメソッドは "__reduce__()" メソッドのインターフ
      ェースと適合していなければなりません。また、メソッドが
      "NotImplemented" を返すことにより、 "dispatch_table" に登録され
      たリデューサにフォールバックして "obj" を直列化することもできま
      す。

      詳細な例については、 型、関数、その他のオブジェクトに対するリダ
      クションのカスタマイズ を参照してください。

      バージョン 3.8 で追加.

   fast

      廃止予定です。真値が設定されれば高速モードを有効にします。高速モ
      ードは、メモの使用を無効にします。それにより余分な PUT 命令コー
      ドを生成しなくなるので pickle 化処理が高速化します。自己参照オブ
      ジェクトに対しては使用すべきではありません。さもなければ
      "Pickler" に無限再帰を起こさせるでしょう。

      よりコンパクトな pickle 化を必要とする場合は、
      "pickletools.optimize()" を使用してください。

class pickle.Unpickler(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

   これは pickle データストリームの読み込みのためにバイナリファイルを
   とります。

   pickle のプロトコルバージョンは自動的に検出されます。したがって
   protocol 引数は必要ありません。

   引数 *file* は "io.BufferedIOBase" のインターフェースと同様に、整数
   を引数にとる read() 、バッファを引数にとる readinto() 、引数を取ら
   ない readline() の3つのメソッドを持たなければなりません。したがって
   、 *file* はバイナリ読み込みモードでオープンされたディスク上のファ
   イル、 "io.BytesIO" オブジェクト、または上記インターフェース要件を
   満たす任意のカスタムオブジェクトのいずれかです。

   オプション引数 *fix_imports*, *encoding* および *errors* はPython 2
   で生成された pickle ストリームに対する互換性サポートを制御するため
   に使われます。 *fix_imports* が真の場合、 pickle は古い Python 2 の
   名前を Python 3 の新しい名前に対応づけようとします。 *encoding* と
   *errors* は pickle に Python 2 で  pickle 化された 8 ビット文字列を
   デコードする方法を指定します; これらの引数のデフォルト値はそれぞれ
   'ASCII' と 'strict' です。 *encoding* は 8 ビット文字列インスタンス
   をバイトオブジェクトとして読み込む場合は 'bytes' を指定します。
   Python 2 で pickle 化された NumPy 配列および "datetime", "date",
   "time" の各インスタンスを非 pickle 化するためには
   "encoding='latin1'" を使う必要があります。

   *buffers* が None (デフォルト値) の場合、非直列化に必要な全てのデー
   タは pickle ストリームに含まれている必要があります。これは
   "Pickler" がインスタンス化されたとき (または "dump()" や "dumps()"
   が呼び出されたとき) に *buffer_callback* 引数に None を指定したこと
   に相当します。

   *buffers* が None でない場合、各イテレーションで アウトオブバウンド
   (out-of-band) のバッファビューを参照する pickle ストリームを消費す
   る、バッファ対応のイテラブルでなければなりません。ここに指定するバ
   ッファは Pickler オブジェクトの *buffer_callback* に順番に渡された
   ものです。

   バージョン 3.8 で変更: *buffers* 引数が追加されました。

   load()

      コンストラクターで与えられたオープンしたファイルオブジェクトから
      オブジェクトの pickle 化表現を読み込み、その中で指定されたオブジ
      ェクト階層に再構成して返します。オブジェクトの pickle 化表現より
      後のバイト列は無視されます。

   persistent_load(pid)

      デフォルトで "UnpicklingError" を送出します。

      もし定義されていれば、"persistent_load()" は永続的な ID *pid* に
      よって指定されたオブジェクトを返す必要があります。永続的な ID が
      無効な場合、"UnpicklingError" を送出しなければなりません。

      詳細および使用例については 外部オブジェクトの永続化 を参照してく
      ださい。

   find_class(module, name)

      必要なら *module* をインポートして、そこから *name* という名前の
      オブジェクトを返します。ここで *module* および *name* 引数は
      "str" オブジェクトです。その名前が示唆することに反して
      "find_class()" は関数を探すためにも使われることに注意してくださ
      い。

      サブクラスは、どんな型のオブジェクトを、どのようにロードするか (
      潜在的にはセキュリティリスクの減少) に関する制御を得るためにこれ
      をオーバーライドすることができます。詳細に関しては グローバル変
      数を制限する を参照してください。

      引数 "modulet", "name" を指定して 監査イベント
      "pickle.find_class" を送出します。

class pickle.PickleBuffer(buffer)

   pickle 可能なデータをあらわすバッファのラッパーです。 *buffer* はバ
   ッファライクなオブジェクト (*bytes-like object*) や N 次元配列のよ
   うな バッファ機能を提供する オブジェクトでなければなりません。

   "PickleBuffer" はそれ自身バッファ機能を提供します。したがってこのク
   ラスのインスタンスを、バッファ機能を提供するオブジェクトを期待する
   "memoryview" など他の API に渡すことが可能です。

   "PickleBuffer" オブジェクトはプロトコル 5 以上でのみ直列化可能で、
   アウトオブバウンド (out-of-band) の直列化 に対応しています。

   バージョン 3.8 で追加.

   raw()

      このバッファの背後にあるメモリ領域への "memoryview" を返します。
      戻り値のオブジェクトはフォーマット "B" (符号なしバイト) の C-連
      続な1次元のメモリビューです。バッファが C-連続でも Fortran-連続
      でもない場合 "BufferError" 例外が送出されます。

   release()

      PickleBuffer オブジェクトを通じてアクセスされる背後のバッファを
      解放します。


pickle 化、非 pickle 化できるもの
=================================

以下の型は pickle 化できます:

* "None" 、 "True" 、および "False"

* 整数、浮動小数点数、複素数

* 文字列、バイト列、バイト配列

* pickle 化可能なオブジェクトからなるタプル、リスト、集合および辞書

* モジュールのトップレベルで定義された関数 ("def" で定義されたもののみ
  で "lambda" で定義されたものは含まない)

* モジュールのトップレベルで定義されているクラス

* "__dict__" 属性を持つクラス、あるいは "__getstate__()" メソッドの返
  り値が pickle 化可能なクラス (詳細は クラスインスタンスの pickle 化
  を参照)。

pickle 化できないオブジェクトを pickle 化しようとすると、
"PicklingError" 例外が送出されます。この例外が起きたとき、すでに元のフ
ァイルには未知の長さのバイト列が書き込まれている場合があります。極端に
再帰的なデータ構造を pickle 化しようとした場合には再帰の深さ制限を越え
てしまうかもしれず、この場合には "RecursionError" が送出されます。この
制限は、"sys.setrecursionlimit()" で慎重に上げていくことは可能です。

関数 (組込みおよびユーザー定義) は、値ではなく、完全 *修飾名* で
pickle 化されます。[2]  これは、関数名のみがそれを含んでいるモジュール
およびクラスの名前をともなって pickle 化されることを意味します。関数の
コードやその属性は pickle 化されません。すなわち、非 pickle 化する環境
で定義したモジュールがインポート可能な状態になっており、そのモジュール
内に関数名のオブジェクトが含まれていなければなりません。この条件を満た
さなかった場合は例外が送出されます。[3]

クラスも同様に完全修飾名で pickle 化されるので、unpickle 化環境には同
じ制限が課せられます。クラス中のコードやデータは何も pickle 化されない
ので、以下の例ではクラス属性 "attr" が unpickle 化環境で復元されないこ
とに注意してください:

   class Foo:
       attr = 'A class attribute'

   picklestring = pickle.dumps(Foo)

pickle 化可能な関数やクラスがモジュールのトップレベルで定義されていな
ければならないのはこれらの制限のためです。

同様に、クラスのインスタンスが pickle 化された際、そのクラスのコードお
よびデータはオブジェクトと一緒に pickle 化されることはありません。イン
スタンスのデータのみが pickle 化されます。この仕様は、クラス内のバグを
修正したりメソッドを追加した後でも、そのクラスの以前のバージョンで作ら
れたオブジェクトを読み出せるように意図的に行われています。あるクラスの
多くのバージョンで使われるような長命なオブジェクトを作ろうと計画してい
るなら、そのクラスの "__setstate__()" メソッドによって適切な変換が行わ
れるようにオブジェクトのバージョン番号を入れておくとよいかもしれません
。


クラスインスタンスの pickle 化
==============================

この節では、クラスインスタンスがどのように pickle 化または非 pickle 化
されるのかを定義したり、カスタマイズしたり、コントロールしたりするのに
利用可能な一般的機構について説明します。

ほとんどの場合、インスタンスを pickle 化できるようにするために追加のコ
ードは必要ありません。デフォルトで、pickle はインスタンスのクラスと属
性を内省によって検索します。クラスインスタンスが非 pickle 化される場合
、通常その "__init__()" メソッドは実行 *されません* 。デフォルトの振る
舞いは、最初に初期化されていないインスタンスを作成して、次に保存された
属性を復元します。次のコードはこの振る舞いの実装を示しています:

   def save(obj):
       return (obj.__class__, obj.__dict__)

   def restore(cls, attributes):
       obj = cls.__new__(cls)
       obj.__dict__.update(attributes)
       return obj

クラスは、いくつかの特殊メソッドを提供することによって、デフォルトの振
る舞いを変更することができます:

object.__getnewargs_ex__()

   プロトコル 2 以上の場合、 "__getnewargs_ex__()" メソッドを実装した
   クラスは "__new__()" メソッドに渡された値の非 pickle 化の方法を指示
   することができます。このメソッドは、オブジェクトの生成に必要な位置
   引数のタプル *args* と名前付き引数の辞書 *kwargs* のペア "(args,
   kwargs)" を返さなければなりません。これらは非 pickle 化に際して
   "__new__()" メソッドに渡されます。

   クラスの "__new__()" メソッドがキーワード専用引数を求める場合はこの
   メソッドを実装すべきです。 そうしない場合、互換性のため
   "__getnewargs__()" メソッドの実装を推奨します。

   バージョン 3.6 で変更: "__getnewargs_ex__()" がプロトコル 2 と 3 で
   も使われるようになりました。

object.__getnewargs__()

   このメソッドは "__getnewargs_ex__()" と同じような機能を提供しますが
   、位置引数のみをサポートします。このメソッドは引数のタプル "args"
   を返さなければならず、戻り値は非 pickle 化に際して "__new__()" メソ
   ッドに渡されます。

   "__getnewargs_ex__()" が定義されていると "__getnewargs__()" は呼び
   出しません。

   バージョン 3.6 で変更: Python 3.6以前のプロトコル 2 と 3 では、
   "__getnewargs_ex__()" の代わりに "__getnewargs__()" が呼び出されて
   いました。

object.__getstate__()

   クラスはそのインスタンスをどう pickle 化するかについてさらに影響を
   与えることができます; クラスに "__getstate__()" メソッドが定義され
   ていた場合それが呼ばれ、返り値のオブジェクトはインスタンスの辞書で
   はなく、インスタンスの内容が pickle 化されたものになります。
   "__getstate__()" がないときは通常通りインスタンスの "__dict__" が
   pickle 化されます。

object.__setstate__(state)

   非 pickle 化に際して、クラスが "__setstate__()" を定義している場合
   、それは非 pickle 化された状態とともに呼び出されます。その場合、状
   態オブジェクトが辞書でなければならないという要求はありません。そう
   でなければ、 pickle された状態は辞書で、その要素は新しいインスタン
   スの辞書に割り当てられます。

   注釈:

     "__getstate__()" が偽値を返す場合、非 pickle 化時に
     "__setstate__()" メソッドは呼ばれません。

"__getstate__()" および "__setstate__()" メソッドの使い方に関する詳細
な情報については 状態を持つオブジェクトの扱い 節を参照してください。

注釈:

  非 pickle 化に際しては、 "__getattr__()", "__getattribute__()", また
  は "__setattr__()" といったメソッドがインスタンスに対して呼ばれるこ
  とがあります。これらのメソッドが何らかの内部の不変な条件が真であるこ
  とを必要とする場合、その型は "__new__()" メソッドを実装してそのよう
  な不変な条件を構築すべきです。なぜならばインスタンスの非 pickle 化に
  おいては "__init__()" メソッドは呼ばれないからです。

これらから見るように、pickle は上記のメソッドを直接使用しません。実際
には、これらのメソッドは "__reduce__()" 特殊メソッドを実装するコピープ
ロトコルの一部です。コピープロトコルは、pickle 化とオブジェクトのコピ
ーに必要な、データを取得するための統一されたインターフェースを提供しま
す。 [4]

強力ですが、クラスに "__reduce__()" メソッドを直接実装することはエラー
を起こしやすくなります。この理由のため、クラスの設計者は可能なかぎり高
レベルインターフェース ("__getnewargs_ex__()"、"__getstate__()" および
"__setstate__()") を使用するべきです。公開はしているものの、
"__reduce__()" の使用は、あくまでオプションとして、より効果的な pickle
化につながる場合、あるいはその両方の場合のみにしてください。

object.__reduce__()

   このインターフェースは現在、以下のように定義されています。
   "__reduce__()" メソッドは引数を取らず、文字列あるいは (こちらの方が
   好まれますが) タプルのいずれかを返すべきです (返されたオブジェクト
   は、しばしば "reduce value" と呼ばれます)。

   文字列が返された場合、その文字列はグローバル変数の名前として解釈さ
   れます。それはオブジェクトのモジュールから見たローカル名であるべき
   です; pickle モジュールは、オブジェクトのモジュールを決定するために
   モジュールの名前空間を検索します。この振る舞いは、典型的にシングル
   トンで便利です。

   タプルが返された場合、それは 2〜6 要素長でなければなりません。オプ
   ションのアイテムは省略することができます。あるいはそれらの値として
   "None" を渡すことができます。各要素の意味は順に:

   * オブジェクトの初期バージョンを作成するために呼ばれる呼び出し可能
     オブジェクト。

   * 呼出し可能オブジェクトに対する引数のタプル。呼出し可能オブジェク
     トが引数を受け取らない場合、空のタプルが与えられなければなりませ
     ん。

   * 任意で、前述のオブジェクトの "__setstate__()" メソッドに渡される
     オブジェクトの状態。オブジェクトがそのようなメソッドを持たない場
     合、値は辞書でなければならず、それはオブジェクトの "__dict__" 属
     性に追加されます。

   * 任意で、連続した要素を yield する (シーケンスではなく) イテレータ
     ー。これらの要素は "obj.append(item)" を使用して、あるいはバッチ
     では "obj.extend(list_of_items)" を使用して、オブジェクトに追加さ
     れます。これは主としてリストのサブクラスに対して使用されますが、
     適切なシグネチャを持つ "append()" および "extend()" メソッドがあ
     るかぎり、他のクラスで使用することもできます。 ("append()" または
     "extend()" のどちらが使用されるかは、どの pickle プロトコルバージ
     ョンが使われるかに加えて追加されるアイテムの数にも依存します。し
     たがって、両方をサポートする必要があります)

   * 任意で、連続する key-value ペアを yield する (シーケンスでなく)
     イテレーター。これらの要素は "obj[key] = value" を使用して、オブ
     ジェクトに格納されます。これは主として辞書のサブクラスに対して使
     用されますが、"__setitem__()" を実装しているかぎり他のクラスで使
     用することもできます。

   * 任意で、シグネチャが "(obj, state)" である呼び出し可能オブジェク
     ト。このオブジェクトは、 "obj" のスタティックな "__setstate__()"
     メソッドの代わりに、ユーザーがオブジェクトの状態を更新する方法を
     プログラム的に制御することを許します。 "None" 以外の場合、この呼
     び出し可能オブジェクトは "obj" の "__setstate__()" メソッドに優先
     します。

     バージョン 3.8 で追加: 任意の6番目のタプル要素 "(obj, state)" が
     追加されました。

object.__reduce_ex__(protocol)

   別の方法として、"__reduce_ex__()" メソッドを定義することもできます
   。唯一の違いは、このメソッドは単一の整数引数、プロトコルバージョン
   を取る必要があるということです。もし定義された場合、pickle は
   "__reduce__()" メソッドよりもこのメソッドを優先します。さらに、
   "__reduce__()" は自動的に拡張版の同義語になります。このメソッドの主
   な用途は、古い Python リリースに対して後方互換性のある reduce value
   を提供することです。


外部オブジェクトの永続化
------------------------

オブジェクトの永続化のために、"pickle" モジュールは、pickle データスト
リーム外のオブジェクトに対する参照の概念をサポートしています。そのよう
なオブジェクトは永続的 ID によって参照されます。それは、英数文字の文字
列 (プロトコル 0 に対して) [5] あるいは単に任意のオブジェクト (より新
しい任意のプロトコルに対して) のいずれかです。

そのような永続的 ID の分解能は "pickle" モジュールでは定義されていませ
ん; これはこの分解能を pickler および unpickler のそれぞれ
"persistent_id()" および "persistent_load()" 上でのユーザー定義メソッ
ドに移譲します。

外部の永続的 ID を持つ pickle オブジェクトの pickler は、引数にオブジ
ェクトを取り、"None" かオブジェクトの永続的 ID を返すカスタム
"persistent_id()" メソッドを持たなくてはなりません。"None" を返す場合
、pickler は通常通りマーカーとともにオブジェクトを pickle 化するため、
unpickler はそれを永続的 ID として認識します。

外部オブジェクトを非 pickle 化するには、unpickler は永続的 ID オブジェ
クトを取り被参照オブジェクトを返すカスタム "persistent_load()" メソッ
ドを持たなくてはなりません。

これは、外部のオブジェクトを参照によって pickle 化するために永続的 ID
をどのように使用するかを示す包括的な例です。

   # Simple example presenting how persistent ID can be used to pickle
   # external objects by reference.

   import pickle
   import sqlite3
   from collections import namedtuple

   # Simple class representing a record in our database.
   MemoRecord = namedtuple("MemoRecord", "key, task")

   class DBPickler(pickle.Pickler):

       def persistent_id(self, obj):
           # Instead of pickling MemoRecord as a regular class instance, we emit a
           # persistent ID.
           if isinstance(obj, MemoRecord):
               # Here, our persistent ID is simply a tuple, containing a tag and a
               # key, which refers to a specific record in the database.
               return ("MemoRecord", obj.key)
           else:
               # If obj does not have a persistent ID, return None. This means obj
               # needs to be pickled as usual.
               return None


   class DBUnpickler(pickle.Unpickler):

       def __init__(self, file, connection):
           super().__init__(file)
           self.connection = connection

       def persistent_load(self, pid):
           # This method is invoked whenever a persistent ID is encountered.
           # Here, pid is the tuple returned by DBPickler.
           cursor = self.connection.cursor()
           type_tag, key_id = pid
           if type_tag == "MemoRecord":
               # Fetch the referenced record from the database and return it.
               cursor.execute("SELECT * FROM memos WHERE key=?", (str(key_id),))
               key, task = cursor.fetchone()
               return MemoRecord(key, task)
           else:
               # Always raises an error if you cannot return the correct object.
               # Otherwise, the unpickler will think None is the object referenced
               # by the persistent ID.
               raise pickle.UnpicklingError("unsupported persistent object")


   def main():
       import io
       import pprint

       # Initialize and populate our database.
       conn = sqlite3.connect(":memory:")
       cursor = conn.cursor()
       cursor.execute("CREATE TABLE memos(key INTEGER PRIMARY KEY, task TEXT)")
       tasks = (
           'give food to fish',
           'prepare group meeting',
           'fight with a zebra',
           )
       for task in tasks:
           cursor.execute("INSERT INTO memos VALUES(NULL, ?)", (task,))

       # Fetch the records to be pickled.
       cursor.execute("SELECT * FROM memos")
       memos = [MemoRecord(key, task) for key, task in cursor]
       # Save the records using our custom DBPickler.
       file = io.BytesIO()
       DBPickler(file).dump(memos)

       print("Pickled records:")
       pprint.pprint(memos)

       # Update a record, just for good measure.
       cursor.execute("UPDATE memos SET task='learn italian' WHERE key=1")

       # Load the records from the pickle data stream.
       file.seek(0)
       memos = DBUnpickler(file, conn).load()

       print("Unpickled records:")
       pprint.pprint(memos)


   if __name__ == '__main__':
       main()


ディスパッチテーブル
--------------------

pickle 化に依存する他のコードの邪魔をせずに、一部のクラスの pickle 化
だけをカスタマイズしたい場合、プライベートのディスパッチテーブルを持つ
pickler を作成することができます。

"copyreg" モジュールによって管理されるグローバルなディスパッチテーブル
は "copyreg.dispatch_table" として利用可能です。したがって、
"copyreg.dispatch_table" の修正済のコピーをプライベートのディスパッチ
テーブルとして使用することを選択できます。

例えば

   f = io.BytesIO()
   p = pickle.Pickler(f)
   p.dispatch_table = copyreg.dispatch_table.copy()
   p.dispatch_table[SomeClass] = reduce_SomeClass

これは "SomeClass" クラスを特別に扱うプライベートのディスパッチテーブ
ルを持つ "pickle.Pickler" のインスタンスを作成します。あるいは、次のコ
ード

   class MyPickler(pickle.Pickler):
       dispatch_table = copyreg.dispatch_table.copy()
       dispatch_table[SomeClass] = reduce_SomeClass
   f = io.BytesIO()
   p = MyPickler(f)

does the same but all instances of "MyPickler" will by default share
the private dispatch table.  On the other hand, the code

   copyreg.pickle(SomeClass, reduce_SomeClass)
   f = io.BytesIO()
   p = pickle.Pickler(f)

modifies the global dispatch table shared by all users of the
"copyreg" module.


状態を持つオブジェクトの扱い
----------------------------

ここでは、クラスを pickle 化する振る舞いの変更手順を紹介しています。
"TextReader" クラスはテキストファイルをオープンし、"readline()" メソッ
ドが呼ばれると、その度に行番号と行の内容を返します。"TextReader" イン
スタンスが pickle 化されるとき、ファイルオブジェクトメンバーを *除く*
すべての属性が保存されます。インスタンスが非 pickle 化されるとき、ファ
イルは再びオープンされ、最後に読み込んだ位置から読み込みを再開します。
このような振る舞いを実装するには "__setstate__()" および
"__getstate__()" メソッドを使用します。

   class TextReader:
       """Print and number lines in a text file."""

       def __init__(self, filename):
           self.filename = filename
           self.file = open(filename)
           self.lineno = 0

       def readline(self):
           self.lineno += 1
           line = self.file.readline()
           if not line:
               return None
           if line.endswith('\n'):
               line = line[:-1]
           return "%i: %s" % (self.lineno, line)

       def __getstate__(self):
           # Copy the object's state from self.__dict__ which contains
           # all our instance attributes. Always use the dict.copy()
           # method to avoid modifying the original state.
           state = self.__dict__.copy()
           # Remove the unpicklable entries.
           del state['file']
           return state

       def __setstate__(self, state):
           # Restore instance attributes (i.e., filename and lineno).
           self.__dict__.update(state)
           # Restore the previously opened file's state. To do so, we need to
           # reopen it and read from it until the line count is restored.
           file = open(self.filename)
           for _ in range(self.lineno):
               file.readline()
           # Finally, save the file.
           self.file = file

使用例は以下のようになるでしょう:

   >>> reader = TextReader("hello.txt")
   >>> reader.readline()
   '1: Hello world!'
   >>> reader.readline()
   '2: I am line number two.'
   >>> new_reader = pickle.loads(pickle.dumps(reader))
   >>> new_reader.readline()
   '3: Goodbye!'


型、関数、その他のオブジェクトに対するリダクションのカスタマイズ
================================================================

バージョン 3.8 で追加.

"dispatch_table" は、ときにその柔軟性が十分でないがことあります。特に
、オブジェクトの型以外の別の条件で pickle 化をカスタマイズしたい場合や
、関数やクラスを使って pickle 化をカスタマイズしたい場合などです。

そのような場合、 "Pickler" クラスから派生したサブクラスで
"reducer_override()" メソッドを実装することができます。このメソッドは
任意のリダクション用タプルを返すことができます  ("__reduce__()" を参照
してください)。もしくは、従来の振る舞いにフォールバックするために
"NotImplemented" を返すこともできます。

"dispatch_table" と "reducer_override()" の両方が定義されている場合、
"reducer_override()" メソッドが優先されます。

注釈:

  パフォーマンス上の理由により、次に挙げるオブジェクトに対しては
  "reducer_override()" が呼ばれないことがあります: "None", "True",
  "False", および "int", "float", "bytes", "str", "dict", "set",
  "frozenset", "list", "tuple" の厳密なインスタンス。

以下は特定のクラスを pickle 化して再構成する単純な例です:

   import io
   import pickle

   class MyClass:
       my_attribute = 1

   class MyPickler(pickle.Pickler):
       def reducer_override(self, obj):
           """Custom reducer for MyClass."""
           if getattr(obj, "__name__", None) == "MyClass":
               return type, (obj.__name__, obj.__bases__,
                             {'my_attribute': obj.my_attribute})
           else:
               # For any other object, fallback to usual reduction
               return NotImplemented

   f = io.BytesIO()
   p = MyPickler(f)
   p.dump(MyClass)

   del MyClass

   unpickled_class = pickle.loads(f.getvalue())

   assert isinstance(unpickled_class, type)
   assert unpickled_class.__name__ == "MyClass"
   assert unpickled_class.my_attribute == 1


アウトオブバウンドバッファ
==========================

バージョン 3.8 で追加.

ある状況では、 "pickle" モジュールは大量のデータを転送するために使われ
ます。 そのため、メモリのコピーを最小限に抑えてパフォーマンスとリソー
スの消費を良好な状態に保つことが重要になることがあります。 しかし、オ
ブジェクトのグラフ的構造をシーケンシャルなバイトストリームに変換する
"pickle" モジュールの通常の処理は、本質的に pickle ストリームへの、ま
たは pickle ストリームからのデータのコピーを伴います。

この制約は、生産者 *provider* (変換されるオブジェクトの型の実装) と消
費者 *consumer* (通信システムの実装) が pickle プロトコル5以上で提供さ
れるアウトオブバウンドのデータ転送機能をサポートしていれば回避できます
。


生産者 API
----------

pickle 化される大きなサイズのデータオブジェクトは、プロトコル5以上でサ
ポートされた "__reduce_ex__()" メソッドを実装しなければなりません。こ
のメソッドは大きなデータに対して ("bytes" オブジェクトなどの代わりに)
"PickleBuffer" インスタンスを返します。

"PickleBuffer" オブジェクトは背後にあるバッファがアウトオブバウンドの
データ転送に適合していることを *知らせます* 。これらのオブジェクトは
"pickle" モジュールの通常の使い方との互換性を保っています。しかし、消
費者側で "pickle" モジュールに対してそれらのバッファを自身で処理するこ
とを事前に知らせることもできます。


消費者 API
----------

通信システムは、オブジェクトグラフを直列化するときに生成された
"PickleBuffer" オブジェクトのカスタマイズされた処理を有効化することが
できます。

送信側は *buffer_callback* 引数を "Pickler" (または "dump()" や
"dumps()" 関数) に渡す必要があります。この関数はオブジェクトグラフを
pickle 化するときに生成されるそれぞれの "PickleBuffer" を引数として呼
ばれます。 *buffer_callback* によって蓄積されたバッファは、それが保持
するデータのコピーを pickle ストリームに送らず、軽量なマーカーが挿入さ
れるだけです。

受信側は *buffers* 引数を "Unpickler" (または "load()" や "loads()" 関
数) に渡す必要があります。これは *buffer_callback* に渡されたバッファ
のイテラブルです。このイテラブルは  *buffer_callback* に渡されたのと同
じ順番でバッファを返さなければなりません。これらのバッファは、pickle
化処理によって "PickleBuffer" オブジェクトを生成したオブジェクトの再構
築処理で期待されるデータを提供します。

送信側と受信側の間で、通信システムはアウトオブバウンドバッファの独自の
転送メカニズムを自由に実装することができます。見込みのある最適化として
は、共有メモリの利用や、データタイプ依存のデータ圧縮などが考えられます
。


使用例
------

以下は、アウトオブバウンドのバッファを使った pickle 処理に関与すること
ができるサブクラス "bytearray" を実装したささいな例です:

   class ZeroCopyByteArray(bytearray):

       def __reduce_ex__(self, protocol):
           if protocol >= 5:
               return type(self)._reconstruct, (PickleBuffer(self),), None
           else:
               # PickleBuffer is forbidden with pickle protocols <= 4.
               return type(self)._reconstruct, (bytearray(self),)

       @classmethod
       def _reconstruct(cls, obj):
           with memoryview(obj) as m:
               # Get a handle over the original buffer object
               obj = m.obj
               if type(obj) is cls:
                   # Original buffer object is a ZeroCopyByteArray, return it
                   # as-is.
                   return obj
               else:
                   return cls(obj)

再構成関数 ("_reconstruct" クラスメソッド) は、受け取ったバッファが持
っているオブジェクトを、それが正しい型であれば、そのまま返します。これ
は、このおもちゃのような例において、ゼロコピーの挙動を模擬的に行う簡単
な方法です。

消費者側では、これらのオブジェクトを通常の方法で pickle 化することがで
きます。この場合非直列化処理は元のオブジェクトのコピーを返します:

   b = ZeroCopyByteArray(b"abc")
   data = pickle.dumps(b, protocol=5)
   new_b = pickle.loads(data)
   print(b == new_b)  # True
   print(b is new_b)  # False: a copy was made

いっぽう直列化において *buffer_callback* を設定し、非直列化において蓄
積されたバッファを渡した場合、コピーではなく元のオブジェクトを得ること
ができます:

   b = ZeroCopyByteArray(b"abc")
   buffers = []
   data = pickle.dumps(b, protocol=5, buffer_callback=buffers.append)
   new_b = pickle.loads(data, buffers=buffers)
   print(b == new_b)  # True
   print(b is new_b)  # True: no copy was made

この例では "bytearray" がそれ自身メモリを割り当てるという性質による制
限があります: すなわち、他のオブジェクトのメモリを参照する "bytearray"
を生成することはできません。しかし、 NumPy 配列のようなサードパーティ
のデータ型ではそのような制限はなく、異なるプロセス間または異なるシステ
ム間で、ゼロコピー (または最小限のコピー) でのpickle 処理の利用が可能
です。

参考: **PEP 574** -- Pickle プロトコルバージョン 5 による帯域外データ


グローバル変数を制限する
========================

デフォルトで、非 pickle 化は pickle データ内で見つけたあらゆるクラスや
関数をインポートします。多くのアプリケーションでは、この振る舞いは受け
入れられません。なぜなら、それによって unpickler が任意のコードをイン
ポートして実行することが可能になるからです。この手の巧妙に作られた
pickle データストリームがロードされたときに何を行うかをちょっと考えて
みてください:

   >>> import pickle
   >>> pickle.loads(b"cos\nsystem\n(S'echo hello world'\ntR.")
   hello world
   0

この例において、unpickler は "os.system()" 関数をインポートして、次に
文字列の引数 "echo hello world" を適用しています。この例は無害ですが、
システムを破壊する例を想像するのは難しくありません。

この理由のため、"Unpickler.find_class()" をカスタマイズすることで非
pickle 化で何を得るかを制御したくなるかもしれません。その名前が示唆す
るのと異なり、"Unpickler.find_class()" はグローバル (クラスや関数) が
必要とした時にはいつでも呼びだされます。したがって、グローバルを完全に
禁止することも安全なサブセットに制限することも可能です。

これは、一部の安全なクラスについてのみ "builtins" モジュールからロード
することを許可する unpickler の例です:

   import builtins
   import io
   import pickle

   safe_builtins = {
       'range',
       'complex',
       'set',
       'frozenset',
       'slice',
   }

   class RestrictedUnpickler(pickle.Unpickler):

       def find_class(self, module, name):
           # Only allow safe classes from builtins.
           if module == "builtins" and name in safe_builtins:
               return getattr(builtins, name)
           # Forbid everything else.
           raise pickle.UnpicklingError("global '%s.%s' is forbidden" %
                                        (module, name))

   def restricted_loads(s):
       """Helper function analogous to pickle.loads()."""
       return RestrictedUnpickler(io.BytesIO(s)).load()

この unpickler が働く使用例は次のように意図されます:

   >>> restricted_loads(pickle.dumps([1, 2, range(15)]))
   [1, 2, range(0, 15)]
   >>> restricted_loads(b"cos\nsystem\n(S'echo hello world'\ntR.")
   Traceback (most recent call last):
     ...
   pickle.UnpicklingError: global 'os.system' is forbidden
   >>> restricted_loads(b'cbuiltins\neval\n'
   ...                  b'(S\'getattr(__import__("os"), "system")'
   ...                  b'("echo hello world")\'\ntR.')
   Traceback (most recent call last):
     ...
   pickle.UnpicklingError: global 'builtins.eval' is forbidden

この例が示すように、非 pickle 化を認めるものに注意しなければなりません
。したがって、セキュリティが重要な場合は "xmlrpc.client" の marshal
API や、サードパーティのソリューションのような別の選択肢を考慮した方が
よいでしょう。


性能
====

pickle プロトコルの最近のバージョン (プロトコル 2 以降) は一部の一般的
な機能と組み込みデータ型を効率的にバイナリにエンコードするよう考慮され
ています。また、"pickle" モジュールは C 言語で書かれた透過的オプティマ
イザーを持っています。


使用例
======

最も単純なコードでは、"dump()" および "load()" 関数を使用してください
。

   import pickle

   # An arbitrary collection of objects supported by pickle.
   data = {
       'a': [1, 2.0, 3+4j],
       'b': ("character string", b"byte string"),
       'c': {None, True, False}
   }

   with open('data.pickle', 'wb') as f:
       # Pickle the 'data' dictionary using the highest protocol available.
       pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)

次の例は、pickle 化されたデータを読み込みます。

   import pickle

   with open('data.pickle', 'rb') as f:
       # The protocol version used is detected automatically, so we do not
       # have to specify it.
       data = pickle.load(f)

参考:

  "copyreg" モジュール
     拡張型を登録するための Pickle インターフェース構成機構。

  "pickletools" モジュール
     pickle データの処理や分析を行うためのツール。

  "shelve" モジュール
     オブジェクトのインデクス付きデータベース; "pickle" を使います。

  "copy" モジュール
     オブジェクトの浅いコピーおよび深いコピー。

  "marshal" モジュール
     組み込み型の高性能な直列化。

-[ 脚注 ]-

[1] "marshal" モジュールと間違えないように注意してください。

[2] なぜ "lambda" 関数を pickle 化できないかというと、すべての
    "lambda" 関数は同じ名前: "<lambda>" を共有しているからです。

[3] 送出される例外は "ImportError" や "AttributeError" になるはずです
    が、他の例外も起こりえます。

[4] "copy" モジュールは、浅いコピーと深いコピーの操作にこのプロトコル
    を使用します。

[5] 英数文字に関する制限は、プロトコル 0 では永続的な ID が改行文字に
    よって区切られるという事実によります。そのため、永続的な ID に何ら
    かの改行文字が含まれると、結果として生じる pickle 化されたデータは
    判読不能になります。
