【发布时间】:2017-08-22 19:59:57
【问题描述】:
如何在 Python 中添加对酸洗传统上不可选择的类型的支持?
我有一个需要腌制的复杂对象,它包括对 NotImplementedType 类的引用。该类是第三方的,所以我不能覆盖它的 __copy__() 或 __deepcopy__() 或 __getstate__() 方法。
我不完全确定为什么 Pickle 不能序列化 NotImplementedType。我敢肯定有一些愚蠢的教条理由,我不在乎。事实是这个类永远不会改变,也不包含任何状态,所以它应该是可序列化的。果然dill package可以序列化这个类就好了。
所以我尝试为NotImplementedType 实现一个自定义的copy_reg 处理程序,该处理程序使用莳萝,例如:
copy_reg.pickle(NotImplementedType,
lambda code: (dill.loads, (dill.dumps(code),)),
dill.loads)
但是,尝试深度复制我的对象会引发异常:
'NoneType' object has no attribute 'update'
来自/usr/lib/python2.7/copy.py 中的第 347 行。深入研究这段代码表明,copy_reg/deepcopy/pickle 模块期望序列化和反序列化实例,而不是对类的引用,并且它抛出这个异常是因为它试图实例化 NotImplementedType 而不是仅仅查找类引用。有什么解决办法吗?
【问题讨论】:
-
我刚刚尝试在 Python 3.6 中对 NotImplementedType 进行酸洗,它就这样发生了,没有任何错误。 (NotImplementedType 获取为
ref = type(NotImplemented)) -
另一方面,我可以确认您在 Python 2.7 中的错误
-
您是否尝试过使用协议 2 显式酸洗? 2.7 上的默认 pickle 协议是 0,并且它缺乏对新式类的许多特性的支持(即使它工作,它在时间和空间上的效率都非常低下)。协议 2 原生支持新型类,它更快、更小,并且可以处理协议 0/1 根本无法处理的许多事情。
-
啊,没关系。我以为
NotImplementedType是一些特殊的第三方东西,看起来它只是type(NotImplemented)。它不适用于 Py2 上的任何协议,它适用于 Py3 上的所有协议,在那里它生成了一个专门的__reduce__,基本上是pickles,以便在反序列化时调用__builtin__.type(__builtin__.NotImplemented)。
标签: python python-2.7 pickle deep-copy