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

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

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

The "pickle" module implements binary protocols for serializing and
de-serializing a Python object structure.  *"Pickling"* is the process
whereby a Python object hierarchy is converted into a byte stream, and
*"unpickling"* is the inverse operation, whereby a byte stream (from a
*binary file* or *bytes-like object*) is converted back into an object
hierarchy.  Pickling (and unpickling) is alternatively known as
"serialization", "marshalling," [1] or "flattening"; however, to avoid
confusion, the terms used here are "pickling" and "unpickling".

警告:

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


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


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

Python has a more primitive serialization module called "marshal", but
in general "pickle" should always be the preferred way to serialize
Python objects.  "marshal" exists primarily to support Python's ".pyc"
files.

The "pickle" module differs from "marshal" in several significant
ways:

* "marshal" cannot be used to serialize user-defined classes and their
  instances.  "pickle" can save and restore class instances
  transparently, however the class definition must be importable and
  live in the same module as when the object was pickled.

* The "marshal" serialization format is not guaranteed to be portable
  across Python versions.  Because its primary job in life is to
  support ".pyc" files, the Python implementers reserve the right to
  change the serialization format in non-backwards compatible ways
  should the need arise. The "pickle" serialization format is
  guaranteed to be backwards compatible across Python releases
  provided a compatible pickle protocol is chosen and pickling and
  unpickling code deals with Python 2 to Python 3 type differences if
  your data is crossing that unique breaking change language boundary.


"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 への直列化および復元を行うための標準ライブラ
    リモジュール。


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

The data format used by "pickle" is Python-specific.  This has the
advantage that there are no restrictions imposed by external standards
such as JSON (which can't represent pointer sharing); however it means
that non-Python programs may not be able to reconstruct pickled Python
objects.

By default, the "pickle" data format uses a relatively compact binary
representation.  If you need optimal size characteristics, you can
efficiently compress pickled data.

The module "pickletools" contains tools for analyzing data streams
generated by "pickle".  "pickletools" source code has extensive
comments about opcodes used by pickle protocols.

現在 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から3.13 までのデフォルトプロトコルでした。プロトコル 4 に
  よる改良に関する情報は **PEP 3154** を参照してください。

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

注釈:

  Serialization is a more primitive notion than persistence; although
  "pickle" reads and writes file objects, it does not handle the issue
  of naming persistent objects, nor the (even more complicated) issue
  of concurrent access to persistent objects.  The "pickle" module can
  transform a complex object into a byte stream and it can transform
  the byte stream into an object with the same internal structure.
  Perhaps the most obvious thing to do with these byte streams is to
  write them onto a file, but it is also conceivable to send them
  across a network or store them in a database.  The "shelve" module
  provides a simple interface to pickle and unpickle objects on DBM-
  style database files.


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

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

The "pickle" module provides the following constants:

pickle.HIGHEST_PROTOCOL

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

pickle.DEFAULT_PROTOCOL

   An integer, the default protocol version used for pickling.  May be
   less than "HIGHEST_PROTOCOL".  Currently the default protocol is 5,
   introduced in Python 3.8 and incompatible with previous versions.
   This version introduces support for out-of-band buffers, where
   **PEP 3118**-compatible data can be transmitted separately from the
   main pickle stream.

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

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

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

The "pickle" module provides the following functions to make the
pickling process more convenient:

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* 引数が追加されました。

The "pickle" module defines three exceptions:

exception pickle.PickleError

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

exception pickle.PicklingError

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

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

exception pickle.UnpicklingError

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

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

The "pickle" module exports three classes, "Pickler", "Unpickler" and
"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 を持つ
      ことができないことに注意してください。

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

      バージョン 3.13 で変更: Add the default implementation of this
      method in the C implementation of "Pickler".

   dispatch_table

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

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

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

      Added in version 3.3.

   reducer_override(obj)

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

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

      Added in version 3.8.

   fast

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

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

   clear_memo()

      Clears the pickler's "memo".

      The memo is the data structure that remembers which objects the
      pickler has already seen, so that shared or recursive objects
      are pickled by reference and not by value.  This method is
      useful when re-using picklers.

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" を送出しなければなりません。

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

      バージョン 3.13 で変更: Add the default implementation of this
      method in the C implementation of "Unpickler".

   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) の直列化 に対応しています。

   Added in version 3.8.

   raw()

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

   release()

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


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

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

* 組み込み定数("None", "True", "False", "Ellipsis", と
  "NotImplemented")

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

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

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

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

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

* instances of such classes for which the result of calling
  "__getstate__()" is picklable  (see section クラスインスタンスの
  pickle 化 for details).

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__()

   In protocols 2 and newer, classes that implement the
   "__getnewargs_ex__()" method can dictate the values passed to the
   "__new__()" method upon unpickling.  The method must return a pair
   "(args, kwargs)" where *args* is a tuple of positional arguments
   and *kwargs* a dictionary of named arguments for constructing the
   object.  Those will be passed to the "__new__()" method upon
   unpickling.

   クラスの "__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__()

   Classes can further influence how their instances are pickled by
   overriding the method "__getstate__()".  It is called and the
   returned object is pickled as the contents for the instance,
   instead of a default state. There are several cases:

   * For a class that has no instance "__dict__" and no "__slots__",
     the default state is "None".

   * For a class that has an instance "__dict__" and no "__slots__",
     the default state is "self.__dict__".

   * For a class that has an instance "__dict__" and "__slots__", the
     default state is a tuple consisting of two dictionaries:
     "self.__dict__", and a dictionary mapping slot names to slot
     values.  Only slots that have a value are included in the latter.

   * For a class that has "__slots__" and no instance "__dict__", the
     default state is a tuple whose first item is "None" and whose
     second item is a dictionary mapping slot names to slot values
     described in the previous bullet.

   バージョン 3.11 で変更: Added the default implementation of the
   "__getstate__()" method in the "object" class.

object.__setstate__(state)

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

   注釈:

     If "__reduce__()" returns a state with value "None" at pickling,
     the "__setstate__()" method will not be called upon unpickling.

"__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" と呼ばれます)。

   If a string is returned, the string should be interpreted as the
   name of a global variable.  It should be the object's local name
   relative to its module; the pickle module searches the module
   namespace to determine the object's module: for a given "obj" to be
   pickled, the "__module__" attribute is looked up on "obj" directly,
   which falls back to a lookup on the type of "obj" if no
   "__module__" instance attribute is set. This behaviour is typically
   useful for singletons.

   タプルが返された場合、それは 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__()" メソッドに優先
     します。

     Added in version 3.8: 任意の6番目のタプル要素 "(obj, state)" が追
     加されました。

object.__reduce_ex__(protocol)

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


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

For the benefit of object persistence, the "pickle" module supports
the notion of a reference to an object outside the pickled data
stream.  Such objects are referenced by a persistent ID, which should
be either a string of alphanumeric characters (for protocol 0) [5] or
just an arbitrary object (for any newer protocol).

The resolution of such persistent IDs is not defined by the "pickle"
module; it will delegate this resolution to the user-defined methods
on the pickler and unpickler, "persistent_id()" and
"persistent_load()" respectively.

外部の永続的 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.


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

Here's an example that shows how to modify pickling behavior for a
class. The "TextReader" class below opens a text file, and returns the
line number and line contents each time its "readline()" method is
called. If a "TextReader" instance is pickled, all attributes *except*
the file object member are saved. When the instance is unpickled, the
file is reopened, and reading resumes from the last location. The
"__setstate__()" and "__getstate__()" methods are used to implement
this behavior.

   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!'


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

Added in version 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


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

Added in version 3.8.

In some contexts, the "pickle" module is used to transfer massive
amounts of data.  Therefore, it can be important to minimize the
number of memory copies, to preserve performance and resource
consumption.  However, normal operation of the "pickle" module, as it
transforms a graph-like structure of objects into a sequential stream
of bytes, intrinsically involves copying data to and from the pickle
stream.

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


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

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

A "PickleBuffer" object *signals* that the underlying buffer is
eligible for out-of-band data transfer.  Those objects remain
compatible with normal usage of the "pickle" module.  However,
consumers can also opt-in to tell "pickle" that they will handle those
buffers by themselves.


消費者 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 や、サードパーティのソリューションのような別の選択肢を考慮した方が
よいでしょう。


性能
====

Recent versions of the pickle protocol (from protocol 2 and upwards)
feature efficient binary encodings for several common features and
built-in types. Also, the "pickle" module has a transparent optimizer
written in 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)


コマンドライン・インターフェース
================================

The "pickle" module can be invoked as a script from the command line,
it will display contents of the pickle files. However, when the pickle
file that you want to examine comes from an untrusted source, "-m
pickletools" is a safer option because it does not execute pickle
bytecode, see pickletools CLI usage.

   python -m pickle pickle_file [pickle_file ...]

The following option is accepted:

pickle_file

   A pickle file to read, or "-" to indicate reading from standard
   input.

参考:

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

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

  "shelve" モジュール
     Indexed databases of objects; uses "pickle".

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

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

-[ 脚注 ]-

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

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

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

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

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