如何挑选对象层次结构,*每个对象通常都有自己的单独文件*,以便快速保存?

How do I pickle an object hierarchy, *each object usually its own individual file* so that saving is fast?

我想使用 pickle,特别是 cPickle 将我的对象的数据序列化为代表模块、项目、模块对象、场景对象等的文件文件夹。有没有简单的方法可以做到这一点?

因此 unpickling 会有点棘手,因为每个父对象存储对 child/sibling 对象的引用,当 运行 但父对象的 pickle 数据将保存对象的文件路径。

我从所有 class 继承的 PathUtil class 开始,但 运行 遇到了问题。有没有人解决过一个类似problem/feature的数据文件保存/恢复的问题?

它与现有代码的协作越透明越好。例如,如果使用元 class __call__ 将使现有的构造函数语法保持不变,那将是一个加号。例如,static __call__ 将首先检查 pickle 文件并加载 it 如果它存在,如果不存在则进行默认构建。

您可以重写 __getstate__ 以写入新的 pickle 文件和 return 其路径,以及 __setstate__ 以取消 pickle 文件。

import pickle, os

DIRNAME = 'path/to/my/pickles/'

class AutoPickleable:

    def __getstate__(self):
        state = dict(self.__dict__)
        path = os.path.join(DIRNAME, str(id(self)))
        with open(path, 'wb') as f:
            pickle.dump(state, f)
        return path

    def __setstate__(self, path):
        with open(path, 'b') as f:
            state = pickle.load(f)
        self.__dict__.update(state)

现在,每个应该具有这种特殊的自动腌制行为的类型都应该子类化 AutoPickleable

当你想转储文件时,你可以pickle.dumps(obj)copy.deepcopy(obj)并忽略结果。

Unpickling 照常工作 (pickle.load)。如果您想从文件路径(而不是 pickle.dumps 的结果)恢复对象,则有点棘手。如果您需要,请告诉我,我会添加详细信息。无论如何,如果你用 "standard" 对象包装你的 AutoPickleable 对象,并对其进行所有 pickle 操作,它应该都有效。

这种方法有几个潜在的问题,但对于 "clean" 案例,例如您描述的案例,它可能会奏效。

一些注意事项:

  • 无法"dynamically"指定要写入的目录。它必须是全局可访问的,并在酸洗操作之前设置
  • 如果多个对象保持引用同一个 AutoPickleable 对象,或者如果您有循环引用(通常,pickle 可以毫无问题地处理这些情况),则可能无法工作
  • 这里没有清理目录/删除文件的代码。