[英]How to unpickle a Python instance that was saved before the class changed a member variable to a property?
我有一个 class 曾经有一个字段data
,但后来 class 被更改,现在data
是一个属性。
我希望能够取消在更改之前腌制的实例,以保持向后兼容性。 一个用于说明的最小示例(在 Python 2 中,尽管在 Python 3 中应该相同):
import pickle
class X(object):
def __init__(self):
self.data = 100
pickle.dump(X(), open("x-file",'w'))
# Redefine the class
class X(object):
def __init__(self):
self._data = 101
@property
def data(self):
return self._data
y = pickle.load(open("x-file")) # cannot access the original data through y
print(y.data)
我想要的是定义一个 function load
来解开 object,检测它是旧样式(例如,通过看到它没有_data
字段),并返回一个带有其数据的新样式实例。 但是,由于字段data
现在是一个属性,旧data
字段被 class 定义覆盖。
有什么简单的方法可以访问旧数据(例如,除了自己解析 pickle 文件之外)?
编辑在彼得伍德的回答之后,我得到了这个解决方案:
import pickle
class X(object):
def __init__(self):
self.data = 100
pickle.dump(X(), open("x-file",'w'))
# Redefine the class
class X(object):
def __init__(self):
self._data = 101
@property
def data(self):
return self._data
def __setstate__(self, state):
if not '_data' in state:
self._data = state['data']
del state['data']
self.__dict__.update(state)
y = pickle.load(open("x-file")) # cannot access the original data through y
print(y.data)
文档中说什么可以腌制和解封? :
如果您计划拥有将看到 class 的多个版本的长期对象,则可能值得在对象中放置一个版本号,以便可以通过类的
__setstate__()
方法进行适当的转换。
这是您可以在类上定义以促进序列化的四种“魔术”方法之一。 请参阅酸洗 Class 实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.