我正在尝试序列化一些我没有编写的代码,并且无法修改需要进行pickle / dilled的代码。该脚本包含一个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行)我怀疑这是我可以改变某些东西以允许新类型的地方。
但是,我不清楚添加自定义类型的目标界面是什么。 (或者也许是为了除了那些之外的所有东西的酸洗,这是可能还是更容易?)
答案 0 :(得分:4)
不,dill._objects
模块只是一个dill可以且不能腌制的类型列表。除此之外,只会让dill
认为它可以做得更多,同时在功能上保持不变。
如果您想添加一个pickler,请使用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,)
是一个args元组,在加载时会传递给你的reconstructer函数。
这可能是最灵活的方式,因为您可以使用recreate_A
的任何功能,包括A.__init__
,如果您需要,但是当您尝试挑选更复杂的类型时,您可能需要进行前/后处理。跳过对象的功能是still in the works,所以如果你想这样做,就必须等待。如果你想达到同样的效果,你可以定义recreate_A
来返回None,并且不带args。