15

Python pickle: deal with updated class definitionsへの回答で、dillパッケージの作成者は次のように書いています。

「わかりました、この機能を github の最新リビジョンに追加しました。思ったよりもはるかに少ないトリックで実装されました...ピクルでクラス定義をシリアル化するだけで、出来上がりです。」

それをインストールdillしていじくり回したので、実際にこの機能を でどのように使用するかは私には明らかではありませんdill。誰かが明確な例を提供できますか? クラスインスタンスをピクルし、クラス定義もシリアライズしたいと思います。

(私は python を初めて使用しますが、この機能は非常に重要だと思われます。なぜなら、オブジェクトをピクルするとき、オブジェクト (シミュレーションの結果である可能性があります) を見ることができるという保証にできるだけ近づくことができるからですクラス定義の後の未来が変更された可能性があり、簡単にアクセスできる方法ですべての変更を追跡していない.)

4

2 に答える 2

12

次の機能のいずれかを探していると思います…</p>

ここでは、クラスとインスタンスを作成してから、クラス定義を変更します。pickle 化されたクラスとインスタンスはdill、デフォルトでクラスのソース コードを pickle 化するため、まだ pickle 化できません…そして、名前空間に同じ名前の複数のクラスを持つことを管理します (クラス定義へのポインター参照を管理するだけでこれを行います)。

Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x+self.y       
...   y = 1
... 
>>> f = Foo()
>>> _Foo = dill.dumps(Foo)
>>> _f = dill.dumps(f)
>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*self.z  
...   z = -1 
... 
>>> f_ = dill.loads(_f, ignore=True)
>>> f_.y
1
>>> f_.bar(1)
2
>>> Foo_ = dill.loads(_Foo)
>>> g = Foo_()
>>> g.bar(1)
2

ピクルは上で爆発します。dillクラスを明示的にシリアライズしたくない場合、およびシリアライズすることを行う場合pickleは、dill参照によるピクルをdill.dumps(Foo, byref=True). ignore=Falseまたは、 (デフォルト)を使用して、新しく定義されたクラスを無視することを動的に決定できます。

以下のケースでは、新しいクラス定義を使用して、オブジェクトからソースを抽出し、ファイルに保存します。さらに、後でインポートできるように、ソースをファイル (ここでは一時ファイルを使用) にダンプできます。

>>> sFoo = dill.source.getsource(Foo)
>>> print sFoo
class Foo(object):
  def bar(self, x):
    return x*self.z
  z = -1

>>> open('myFoo.py', 'w').write(sFoo)    
>>>
>>> f = dill.temp.dump_source(Foo, dir='.')
>>> f.name
'/Users/mmckerns/dev/tmpM1dzYN.py'
>>> from tmpM1dzYN import Foo as _Foo_
>>> h = _Foo_()
>>> h.bar(2)
-2
>>> from myFoo import Foo as _SFoo_
>>> _SFoo_.z
>>> -1
>>> 

それが役立つことを願っています。

于 2014-09-02T12:32:06.043 に答える