您如何添加对在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而不是仅查找类引用。有什么解决办法吗?

最佳答案

所讨论的类实际上包含NotImplementedType的可能性很小。相反,它可能正在腌制NotImplemented,而NotImplemented的归约函数正在尝试根据其类型进行腌制,但是NotImplementedType没有直接公开(您只能通过type(NotImplemented)来获取它),因此尝试创建可以找到NotImplementedType的合格名称的尝试失败。这在Python 3中已解决(移动的另一个参数),但在Python 2中也看起来相当简单,因为为copy_reg定义普通的NotImplementedType处理程序将确保在腌制NotImplemented而不引用其自身类型的情况下。

执行此操作的简单方法是让reducer函数返回命名为NotImplemented的字符串,然后在取消腌制时将其查找为全局字符串。方便地,这意味着您不需要定义任何辅助方法(在解酸侧可能不存在):

copy_reg.pickle(type(NotImplemented), lambda obj: 'NotImplemented')


您根本不需要定义构造函数(第三个copy_reg.pickle参数)。泡菜将包含重新创建NotImplemented所需的所有信息,而不会在解开方面造成任何依赖,使NotImplemented返回而无需尝试序列化NotImplementedType

关于python - 如何 pickle NotImplementedType,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45826043/

10-12 00:24