问题可能出现在反序列化时,因为反序列化所需的类与保存的类不匹配。对此,我们可以使用类似于版本控制的策略,将类的版本嵌入到已保存的数据中。当反序列化时,我们可以检查版本是否匹配,如果不匹配,则使用旧类来反序列化,避免出现属性错误。
以下是示例代码:
import pickle
class Foo:
version = 1 # 类的版本
def __init__(self, value):
self.value = value
# 保存实例到文件
foo = Foo('initial value')
with open('foo.pickle', 'wb') as f:
pickle.dump(foo, f)
# 修改类
class Foo:
version = 2 # 修改版本
# 新增方法
def get_value(self):
return self.value
# 加载实例
with open('foo.pickle', 'rb') as f:
foo = pickle.load(f)
# 查看版本
version = getattr(foo, 'version', 1)
# 根据版本反序列化
if version == Foo.version:
pass # 版本匹配,直接使用
elif version == 1:
# 使用旧类,替换实例
foo.__class__ = Foo
else:
# 无法匹配,抛出异常
raise ValueError(f'Cannot handle version {version} of Foo')
# 使用实例
print(foo.get_value()) # 'initial value'
这样,在修改类后重新读取文件时,即使新类中包含与旧类不同的方法,也不会出现属性错误。