をインポートし__main__
、そのモジュールで使用可能なメソッドを使用することで、グローバル オブジェクトをより適切に処理できます。これは、Python でほとんどすべてのものをシリアライズするためにdillが行うことです。基本的に、dill が対話的に定義された関数をシリアライズする場合、有効なモジュール__main__
を作成するシリアライゼーション側とデシリアライゼーション側の両方で名前マングリングを使用します。__main__
>>> import dill
>>>
>>> def bar(x):
... return foo(x) + x
...
>>> def foo(x):
... return x**2
...
>>> bar(3)
12
>>>
>>> _bar = dill.loads(dill.dumps(bar))
>>> _bar(3)
12
実際、dill はその型をpickle
レジストリに登録するため、使用するブラック ボックス コードがpickle
あり、実際には編集できない場合は、dill をインポートするだけで、サード パーティのコードにモンキーパッチを適用しなくても、魔法のように動作させることができます。
または、インタープリター セッション全体を「python イメージ」として送信したい場合は、dill もそれを行うことができます。
>>> # continuing from above
>>> dill.dump_session('foobar.pkl')
>>>
>>> ^D
dude@sakurai>$ python
Python 2.7.5 (default, Sep 30 2013, 20:15:49)
[GCC 4.2.1 (Apple Inc. build 5566)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> dill.load_session('foobar.pkl')
>>> _bar(3)
12
pickle のバージョン互換性があり、python の変更やインストールに関する通常の注意事項がある限り、イメージを ssh 経由で別のコンピューターに簡単に送信し、中断したところから開始することができます。
私は実際に dill を使用してオブジェクトをシリアル化し、並列 python、 multiprocessing 、およびmpi4pyを使用して並列リソースに送信します。これらを便利にpathosパッケージ (およびMPI の場合はpyinamap
) にまとめます。これにより、さまざまな並列バッチ処理バックエンドに統一されたインターフェイスが提供されます。
>>> # continued from above
>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> Pool(4).map(foo, range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
>>> from pyina.launchers import MpiPool
>>> MpiPool(4).map(foo, range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
ノンブロッキングおよび反復マップ、非並列パイプ接続もあります。用の pathos モジュールもありますが、pp
で定義されている関数についてはやや不安定です__main__
。その改善に取り組んでいます。必要に応じて、github でコードをフォークし、pp
で定義されている関数の改善にご協力ください__main__
。pp
ピクルスがうまくいかない理由はpp
、一時ファイルオブジェクトを使用してインタープリターセッションの履歴を読み取ることによるシリアル化のトリックです...したがって、マルチプロセッシングやmpi4pyと同じ方法でオブジェクトをシリアル化しません。dill.source
使用するのと同じタイプの酸洗をシームレスに行うディルモジュールがありますがpp
、それはかなり新しいものです。