如何加载pickle对象并解析某些引用



假设我们有一个使用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

对于foobarbaz所属的类(以及实际上我们设计中的所有其他类)。

当我们将对象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")

最新更新