我有一个大型对象,我想序列化到磁盘。我发现marshal效果很好而且很快很好。
现在我正在创建我的大对象,然后调用marshal.dump。如果可能的话,我想避免将大对象保存在内存中 - 我希望在构建它时逐步转储它。这可能吗?
对象相当简单,是一个数组字典。
答案 0 :(得分:4)
bsddb模块的'hashopen'和'btopen'函数提供了一个类似于字典的持久接口。也许您可以使用其中一个而不是常规字典来逐步将数组序列化到磁盘?
import bsddb
import marshal
db = bsddb.hashopen('file.db')
db['array1'] = marshal.dumps(array1)
db['array2'] = marshal.dumps(array2)
...
db.close()
检索数组:
db = bsddb.hashopen('file.db')
array1 = marshal.loads(db['array1'])
...
答案 1 :(得分:4)
您的所有对象都必须是列表字典,然后您可以使用shelve module。它提供了一个类似字典的接口,其中键和值存储在数据库文件中而不是存储在内存中。可能会或可能不会影响您的一个限制是Shelf对象中的键必须是字符串。如果在创建Shelf对象时指定protocol = -1以使其使用更有效的二进制表示,则值存储将更有效。
答案 2 :(得分:0)
这在很大程度上取决于你如何构建对象。它是一个子对象数组吗?你可以在构建它时编组/挑选每个数组元素。它是字典吗?同样的想法(marshal / pickle键)
如果它只是一个复杂的哈利对象,你可能想要整理对象的每个部分,然后在你重新阅读时应用你的“构建”过程。
答案 3 :(得分:0)
您应该能够将项目逐段转储到文件中。需要解决的两个设计问题是:
如果您的构建过程一次填充与给定键关联的整个数组,您可能只是将键:数组对作为单独的字典转储到文件中:
big_hairy_dictionary['sample_key'] = pre_existing_array
marshal.dump({'sample_key':big_hairy_dictionary['sample_key']},'central_file')
然后在更新时,每次调用marshal.load('central_file')都会返回一个字典,您可以用它来更新中心字典。但是,当你需要数据时,你想要处理每个键读取'central_file'一次,这真的只会有所帮助。
或者,如果您按任何特定顺序逐个元素填充数组,可以尝试:
big_hairy_dictionary['sample_key'].append(single_element)
marshal.dump(single_element,'marshaled_files/'+'sample_key')
然后,当你加载它时,你不一定需要构建整个字典来取回你需要的东西;你只需要调用marshal.load('marshaled_files / sample_key')直到它返回None,并且你拥有与密钥相关的所有内容。