我正在寻求关于在Python中实现对象持久性的方法的建议。更准确地说,我希望能够将Python对象链接到文件,以便任何打开该文件表示形式的Python进程都共享相同的信息,任何进程都可以更改其对象,并且这些更改会传播到其他进程,即使所有“存储”对象的进程都关闭,文件仍然会保留,并且可以由其他进程重新打开。我发现了三个主要的候选人 - 我的Python发行版 - anydbm,pickle和shelve(dbm看起来是完美的,但它只是Unix,而我在Windows上)。然而,他们都有缺陷:Python对象持久性
- anydbm只能处理字符串值的字典(我正在寻找存储词典列表,它们都具有字符串键和字符串值,但最好我会寻求一个没有类型限制的模块)
- 搁置需要在更改传播之前重新打开文件 - 例如,如果两个进程A和B加载相同的文件(包含已搁置的空列表),并且A将一个项目添加到列表并调用sync(),B仍然会看到列表为空,直到它重新加载文件。
- pickle(我当前用于测试实现的模块)与shelve具有相同的“重新加载要求”,也不会覆盖以前的数据 - 如果进程A将15个空字符串转储到文件上,然后字符串' hello',进程B将不得不加载文件16次以获得'hello'字符串。我正在处理这个问题,通过在重复读取之前进行任何写操作,直到文件结束(“在写入之前清除slate clean”),并重复每次读操作直到文件结束,但是我觉得必须有一个更好的方法。
我的理想模块将表现为如下(以 “A >>>” 通过处理A执行的代码代表,并且 “B >>>” 代码通过处理B执行):
A>>> import imaginary_perfect_module as mod
B>>> import imaginary_perfect_module as mod
A>>> d = mod.load('a_file')
B>>> d = mod.load('a_file')
A>>> d
{}
B>>> d
{}
A>>> d[1] = 'this string is one'
A>>> d['ones'] = 1 #anydbm would sulk here
A>>> d['ones'] = 11
A>>> d['a dict'] = {'this dictionary' : 'is arbitrary', 42 : 'the answer'}
B>>> d['ones'] #shelve would raise a KeyError here, unless A had called d.sync() and B had reloaded d
11 #pickle (with different syntax) would have returned 1 here, and then 11 on next call
(etc. for B)
我可以通过创建我自己的使用pickle的模块来实现这种行为,并编辑转储和加载行为,以便他们使用我上面提到的重复读取 - 但是我发现很难相信这个问题从未发生过,并且已经被修复,之前更有天赋的程序员。此外,对我来说,这些重复的读取看起来效率不高(尽管我必须承认我对操作复杂性的了解是有限的,而且这些重复的读取可能会在“幕后”进行,否则显然会更顺畅)。因此,我得出结论,我必须缺少一些能够为我解决问题的代码模块。如果有人能指出我的方向是正确的,或者对实施提出建议,我将不胜感激。
给看看,以'蒙戈 - db'。它并没有像上面的例子那样完全集成到语言中,但它会为您提供一个比文件系统酸洗更为强大和容忍的数据库,并且对锁定很敏感。 – slezica