ピクルスオブジェクトバージョン化
-
23-09-2019 - |
質問
私は、シリアル化され、使用してディスクに保存されている多数のオブジェクトがあるプロジェクトに取り組んでいます pickle
/cPickle
.
プロジェクトの寿命が進むにつれて(現場の顧客にリリースされた後)、将来の機能/修正により、持続したオブジェクトの一部の署名を変更する必要がある可能性があります。これは、フィールドの追加、フィールドの削除、またはデータの侵入を変更するだけでもあります。
特定のバージョンを持っているとピクルスされるオブジェクトをマークする標準的な方法はありますか( serialVersionUID
Java)?基本的に、FOOバージョン234のインスタンスを復元しているが、現在のコードは236の場合、UPICKLEの通知を受け取りたいと思います。先に進んで自分のソリューションを展開する必要があります(ピタかもしれません)。
ありがとう
解決
pickle
フォーマットにはそのような条件はありません。オブジェクトの属性の「シリアルバージョン番号」の一部を作成して、残りの部分と一緒に正しく漬け込んでみませんか?その後、「通知」は、実際のバージョンと希望のバージョンを比較することで些細なことに持っています。なぜそれがピタであるべきかわからない。
他のヒント
TomaszFrüboesが提案した次のクラスミックスを考えてみましょう ここ.
# versionable.py
class Versionable(object):
def __getstate__(self):
if not hasattr(self, "_class_version"):
raise Exception("Your class must define _class_version class variable")
return dict(_class_version=self._class_version, **self.__dict__)
def __setstate__(self, dict_):
version_present_in_pickle = dict_.pop("_class_version")
if version_present_in_pickle != self._class_version:
raise Exception("Class versions differ: in pickle file: {}, "
"in current class definition: {}"
.format(version_present_in_pickle,
self._class_version))
self.__dict__ = dict_
__getstate__
メソッドはによって呼び出されます pickle
漬物に、そして __setstate__
抑えてピクルスによって呼ばれます。このミックスインクラスは、バージョンを追跡したいクラスのサブクラスとして使用できます。これは次のように使用されます。
# bla.py
from versionable import Versionable
import pickle
class TestVersioning(Versionable):
_class_version = 1
t1 = TestVersioning()
t_pickle_str = pickle.dumps(t1)
class TestVersioning(Versionable):
_class_version = 2
t2 = pickle.loads(t_pickle_str) # Throws exception about wrong class version
所属していません StackOverflow