为什么无法将存储自定义类对象的字典存入shelf文件并正常读取
错误原因
shelve底层依赖pickle实现对象序列化,pickle在序列化自定义类实例时,不会存储类的实现代码,只会记录类名、类所属的模块路径。你在写shelf文件的脚本中,Dog类定义在运行的主模块(__main__)下,而读取shelf的脚本中没有定义相同的Dog类,反序列化时找不到对应类定义,就会抛出AttributeError。
解决方法
方法1:读取脚本中添加相同的Dog类定义
直接把写入脚本里的Dog类复制到读取脚本中即可,修改后的读取代码如下:
# reading shelf file and printing stuff import shelve # 和写入脚本完全一致的Dog类定义 class Dog: def __init__(self, name, age): self.name = name self.age = age with shelve.open('dogs') as sf: d = sf['d'] for k in d.keys(): print(d[k].name, d[k].age)
方法2:将Dog类抽离为公共模块(更推荐,适合多脚本复用场景)
- 新建
dog.py文件,写入Dog类的定义:
# dog.py class Dog: def __init__(self, name, age): self.name = name self.age = age
- 写入shelf的脚本修改为导入公共模块的Dog:
# creating shelf file for testing import shelve from dog import Dog # 从公共模块导入 buddy = Dog("Buddy", 9) miles = Dog("Miles", 4) d = {'buddy': buddy, 'miles': miles} with shelve.open('dogs') as sf: sf['d'] = d
- 读取shelf的脚本也导入公共模块的Dog:
# reading shelf file and printing stuff import shelve from dog import Dog # 从公共模块导入 with shelve.open('dogs') as sf: d = sf['d'] for k in d.keys(): print(d[k].name, d[k].age)
注意:如果后续修改了
Dog类的结构(比如新增/删除属性、修改方法逻辑),之前已经序列化存储的实例反序列化时可能出现不兼容问题,生产环境使用需要做好版本兼容处理。
内容的提问来源于stack exchange,提问作者zsfzu0
相关产品推荐
相关产品推荐

