-
23-09-2019 - |
题
我正在从事一个项目,在该项目中,我们有大量的对象被序列化并存储到磁盘上 pickle
/cPickle
.
随着项目的生活进展(向现场释放客户之后),将来的功能/修复程序可能会要求我们更改某些持久对象的签名。这可能是添加字段,删除字段,甚至只是在数据上更改不变性。
是否有一种标准方法来标记将腌制为具有一定版本的对象(例如 serialVersionUID
在Java)?基本上,如果我正在恢复FOO版本234的实例,但是当前代码为236,我想收到一些未列出的通知。我应该继续前进并推出自己的解决方案(可能是PITA)。
谢谢
解决方案
这 pickle
格式没有这样的条件。您为什么不只是将对象属性的“序列版号”部分与其他属性一起腌制?然后,可以通过比较实际和所需的版本来微不足道的“通知” - 不要理解为什么它应该是PITA。
其他提示
考虑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__
帕克(Pickle)在没有挑剔的情况下称呼。此混合类可以用作您要跟踪的版本的类的子类。这应如下:
# 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