Python 如何将自定义类型添加到dill';腌制型

Python 如何将自定义类型添加到dill';腌制型,python,pymongo,dill,Python,Pymongo,Dill,我正在尝试序列化一些我没有编写并且无法修改的代码,这些代码需要进行pickle/dilled。该脚本包含一个mongodb集合对象——它以后不会实际使用,但会抛出一个错误。当我尝试dilling它时,我收到错误: Collection object is not callable. If you meant to call __getnewargs__ method on a 'Database' object it is failing because no such method exis

我正在尝试序列化一些我没有编写并且无法修改的代码,这些代码需要进行pickle/dilled。该脚本包含一个mongodb集合对象——它以后不会实际使用,但会抛出一个错误。当我尝试dilling它时,我收到错误:

Collection object is not callable.  If you meant to call __getnewargs__ method on a 'Database' object it is failing because no such method exists.
我在这里看到的代码正在枚举接受的类型: (第132-190行)我怀疑在这里我可能会改变一些东西来允许一种新的类型


但是,我不清楚用于添加自定义类型的预期接口是什么。(或者可能用于酸洗除此之外的所有东西,这是可能的还是更容易的?

不,dill.\u objects模块只是dill可以和不能酸洗的类型列表。再加上这一点,只会让dill认为它可以做得更多,同时在功能上保持不变

如果你想添加一个pickler,可以使用dill.register(通常作为装饰器)。它需要一个函数来进行分解。例如,给定一个不可粘贴的类别:

class A:
    def __init__(self, a):
        self.a = a
    def __reduce__(self):
        raise GoAwayError()
尝试对
A
的一个实例进行pickle操作将为您提供:

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
recreate\u A
是用于重建的函数,
(obj.A,)
是一个参数元组,加载时将传递给重建器函数


这可能是最灵活的方法,因为您可以使用任何函数来
重新创建A
,包括
A.。\uuuu init\uuu
,如果需要的话,但是当您尝试pickle更复杂的类型时,您可能需要进行预/后处理。跳过对象的功能是,因此如果要这样做,您必须等待。如果你想达到同样的效果,你可以定义
recreate\u A
来返回None,并且不接受任何参数。

no,dill.\u objects模块只是dill可以和不能pickle的类型列表。再加上这一点,只会让dill认为它可以做得更多,同时在功能上保持不变

如果你想添加一个pickler,可以使用dill.register(通常作为装饰器)。它需要一个函数来进行分解。例如,给定一个不可粘贴的类别:

class A:
    def __init__(self, a):
        self.a = a
    def __reduce__(self):
        raise GoAwayError()
尝试对
A
的一个实例进行pickle操作将为您提供:

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
recreate\u A
是用于重建的函数,
(obj.A,)
是一个参数元组,加载时将传递给重建器函数


这可能是最灵活的方法,因为您可以使用任何函数来
重新创建A
,包括
A.。\uuuu init\uuu
,如果需要的话,但是当您尝试pickle更复杂的类型时,您可能需要进行预/后处理。跳过对象的功能是,因此如果要这样做,您必须等待。如果你想达到同样的效果,你可以定义
reacreate\u A
来返回None,不接受args。

如果你想fork
dill
将你的特定类型添加到
dill
。。。然后按照@matsjoyce说的去做,但是你可以编辑文件
dill.dill.py
来直接添加你的类型,而不是注册它。如果你看
dill.dill
,它基本上是这些
注册的
函数的集合。我不认为dill会负责显式管理这种外来的第三方类型——但是,如果您发现一种非常常见的导致问题的底层类型,那么这就更有可能获得成功的公关。Mike McKerns,如果我想添加一个新类型,但无法在我的环境中直接编辑dill源代码,您有什么建议吗?这是monkeypatch的情况吗?照我回答的做?你不需要为此编辑dill。很明显,
recreate\u A
是反序列化程序,但是如何指定序列化程序?
save\u A
是序列化程序。如果你想fork
dill
将你的特定类型添加到
dill
。。。然后按照@matsjoyce说的去做,但是你可以编辑文件
dill.dill.py
来直接添加你的类型,而不是注册它。如果你看
dill.dill
,它基本上是这些
注册的
函数的集合。我不认为dill会负责显式管理这种外来的第三方类型——但是,如果您发现一种非常常见的导致问题的底层类型,那么这就更有可能获得成功的公关。Mike McKerns,如果我想添加一个新类型,但无法在我的环境中直接编辑dill源代码,您有什么建议吗?这是monkeypatch的情况吗?照我回答的做?您不需要为此编辑dill。很明显,
recreate\u A
是反序列化程序,但是如何指定序列化程序?
save\u A
是序列化程序。