How to add a custom type to dill's pickleable types

主宰稳场 提交于 2019-12-06 15:52:45

No, the dill._objects module is just a list of types dill can and cannot pickle. Adding to that will just make dill think it can do more, while remaining the same functionally.

If you want to add a pickler, use dill.register (usally as a decorator). It takes a function which does the breaking down. E.g. given an unpicklable class:

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

Trying to pickle an instance of A will give you:

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

You can define a pickler like:

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 is the function used for reconstruction, and (obj.a,) is a tuple of args which will be passed to your reconstructer function when loading.

This is probably the most flexible way of doing it, as you can use any function for recreate_A, including A.__init__ if you need to, but as you are trying to pickle a more complex type, you may need to do pre/post-processing. The functionality for skipping objects is still in the works, so you'll have to wait if you want to do it that way. If you want to achieve the same effect, you could just define recreate_A to return None, and take no args.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!