我想使用pickle,特别是cPickle将我的对象数据序列化为表示模块,项目,模块对象,场景对象等的文件文件夹。 有没有简单的方法可以做到这一点?
因此,取消酸洗将有点棘手,因为每个父对象在运行时存储对子/同级对象的引用,但父对象的 pickle 数据将保存该对象的文件路径。
我从一个所有类都继承的 PathUtil 类开始,但一直遇到问题。 有没有人解决过类似的数据文件保存/恢复问题/功能?
它与现有代码配合得越透明越好。 例如,如果使用元类__call__
将使现有的构造函数语法保持不变,那将是一个加号。 例如,静态__call__
将首先检查 pickle 文件并加载它(如果存在),如果不存在,则执行默认构造。
您可以重写__getstate__
以写入新的 pickle 文件并返回其路径,__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)
并忽略结果。
脱洗照常工作(pickle.load
)。 如果要从文件路径(而不是从pickle.dumps
的结果)还原对象,则有点棘手。如果你想要它,请告诉我,我会添加详细信息。 无论如何,如果您用"标准"对象包装AutoPickleable
对象,并对其执行所有泡菜操作,则它应该都可以工作。
这种方法有几个潜在的问题,但对于您描述的"干净"情况,它可能会起作用。
一些注意事项:
- 无法"动态"指定要写入的目录。它必须是全局可访问的,并在酸洗操作之前进行设置
- 如果多个对象保持对同一
AutoPickleable
对象的引用,或者如果您有循环引用,则可能不起作用(通常,pickle 处理这些情况没有问题) - 这里没有清理目录/删除文件的代码。