Pythonでオブジェクトの永続性を実装する方法についてアドバイスを求めています。もっと正確に言うと、Pythonオブジェクトをファイルにリンクして、そのファイルの表現を開くPythonプロセスが同じ情報を共有し、どのプロセスもそのオブジェクトを変更でき、その変更がに伝播するようにしたいと思います。他のプロセス、およびオブジェクトを「保存」しているすべてのプロセスが閉じられた場合でも、ファイルは残り、別のプロセスで再度開くことができます。
私はPythonのディストリビューションでこれの3つの主要な候補を見つけました-anydbm、pickle、shelve(dbmは完璧に見えましたが、Unixのみであり、私はWindowsを使用しています)。ただし、それらにはすべて欠陥があります。
- anydbmは文字列値の辞書のみを処理できます(すべてに文字列キーと文字列値を持つ辞書のリストを格納しようとしていますが、理想的には型制限のないモジュールを探します)
- シェルフでは、変更が伝播する前にファイルを再度開く必要があります。たとえば、2つのプロセスAとBが同じファイル(シェルフされた空のリストを含む)をロードし、Aがリストにアイテムを追加してsync()を呼び出す場合、Bはファイルをリロードするまで、リストは空であると見なされます。
- pickle(現在テスト実装に使用しているモジュール)には、shelveと同じ「リロード要件」があり、以前のデータを上書きしません。プロセスAが15個の空の文字列をファイルにダンプし、次に文字列'hello'をダンプする場合、プロセスBは、「hello」文字列を取得するためにファイルを16回ロードする必要があります。私は現在、書き込み操作の前にファイルの終わりまで繰り返し読み取りを行い(「書き込み前にスレートをきれいに拭く」)、すべての読み取り操作をファイルの終わりまで繰り返すことでこの問題に対処していますが、より良い方法。
私の理想的なモジュールは次のように動作します(「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を使用する独自のモジュールを作成し、上記の繰り返し読み取りを使用するようにダンプとロードの動作を編集することで、この動作を実現できましたが、この問題が発生したことがなく、修正されたとは信じられません。以前は、より才能のあるプログラマーによって。さらに、これらの繰り返しの読み取りは私には非効率に思えます(ただし、操作の複雑さに関する知識は限られており、これらの繰り返しの読み取りは、棚のような明らかに滑らかなモジュールの「舞台裏」で行われている可能性があります)。したがって、私は私のために問題を解決するいくつかのコードモジュールが欠けているに違いないと結論付けます。誰かが私を正しい方向に向けたり、実装についてアドバイスをくれたりしてくれたらありがたいです。