我正在尋求關於在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