假设我们有一个使用pickle
写入二进制文件的对象。假设对象图如下所示:
foo1
+--->bar
| --->context
+--->baz
| +--->context
| --->qux
--->context
现在context
对象是大型数据结构,并且qux的所有实例都是相同的。因此,我们决定将这些contexxt
对象排除在pickle过程之外:
def __getstate__(self):
my_dict = dict(self.__dict__)
my_dict['context'] = None # We don't save the context
return my_dict
对于foo
、bar
和baz
所属的类(以及实际上我们设计中的所有其他类)。
当我们将对象load()
回调到内存中时,我们希望所有context
引用都设置回给定的上下文。可以通过递归遍历对象树来实现这一点,但我们想知道pickle
中是否有更优雅的解决方案,可以在将数据加载回内存时填充context
值本身?
如果.context
的类型为Context
,而不是将context
设置为None
,则可以调整pickle
文档中"外部对象的持久性"一节中的代码:
import pickle
class ContextAwarePickler(pickle.Pickler):
def persistent_id(self, obj):
# if this is a context, return the key
if isinstance(obj, Context):
return ("Context", context.key)
# pickle as usual
return None
class ContextAwareUnpickler(pickle.Unpickler):
def recover_context(self, key_id):
...
def persistent_load(self, pid):
type_tag, key_id = pid
if type_tag == "Context":
return self.recover_context(key_id)
else:
raise pickle.UnpicklingError("unsupported persistent object")