1

私が書いていないコードをシリアライズしようとしていますが、それを変更することはできません。スクリプトには mongodb コレクション オブジェクトが含まれています。これは実際には後で使用されませんが、それをディリングするとエラーがスローされます。ディリングしようとすると、次のエラーが表示されます。

Collection object is not callable.  If you meant to call __getnewargs__ method on a 'Database' object it is failing because no such method exists.

受け入れられた型を列挙しているコードがここにあります: https://github.com/uqfoundation/dill/blob/master/dill/_objects.py (行 132-190) そして、私の疑いは、これが私が何かを変更する場所であるということです新しいタイプを許可します。

ただし、カスタム型を追加するための意図したインターフェイスが何であるかは明確ではありません。(または、それ以外のすべてを酸洗する場合、それは可能ですか、それとも簡単ですか?)

4

1 に答える 1

4

いいえ、dill._objectsモジュールは dill が pickle できる型とできない型の単なるリストです。それに追加するとdill、機能的には同じままで、より多くのことができるようになります。

ピクラーを追加したい場合は、dill.register(通常はデコレーターとして) を使用します。分解を行う関数を取ります。たとえば、ピクルできないクラスが与えられた場合:

class A:
    def __init__(self, a):
        self.a = a
    def __reduce__(self):
        raise GoAwayError()

のインスタンスをピクルしようとすると、次のようにAなります。

Traceback (most recent call last):
  File "d.py", line 9, in <module>
    dill.dumps(A(1))
  File "/home/matthew/GitHub/dill/dill/dill.py", line 192, in dumps
    dump(obj, file, protocol, byref, fmode)#, strictio)
  File "/home/matthew/GitHub/dill/dill/dill.py", line 182, in dump
    pik.dump(obj)
  File "/usr/lib/python3.4/pickle.py", line 410, in dump
    self.save(obj)
  File "/usr/lib/python3.4/pickle.py", line 497, in save
    rv = reduce(self.proto)
  File "d.py", line 7, in __reduce__
    raise GoAwayError()
NameError: name 'GoAwayError' is not defined

次のようなピッカーを定義できます。

def recreate_A(a):
    return A(a)

@dill.register(A)
def save_A(pickler, obj):
    pickler.save_reduce(recreate_A, (obj.a,), obj=obj)

recreate_A再構築に使用される関数であり(obj.a,)、ロード時に再構築関数に渡される引数のタプルです。

必要に応じて任意の関数を使用できるため、これはおそらく最も柔軟な方法ですrecreate_AA.__init__、より複雑な型をピクルしようとしている場合は、前処理/後処理が必要になる場合があります。オブジェクトをスキップする機能はまだ開発中なので、そのようにしたい場合は待つ必要があります。同じ効果を達成したい場合は、recreate_ANone を返すように定義し、引数を取らないことができます。

于 2014-12-08T09:12:12.690 に答える