您如何添加对在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/