You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用shelve反序列化时出现AttributeError:无法获取Employee属性的原因

问题原因与解决办法

核心原因

shelve模块底层依赖pickle实现对象的序列化与反序列化,而pickle保存对象时,并不会把类的完整代码存进文件,只记录类的名称和它所在的模块路径。

  • 在定义Employee和Manager的原模块中读取时,当前代码环境已经加载了这两个类的定义,pickle能直接找到对应类,所以读取正常。
  • 在新文件中读取时,当前代码环境既没有这两个类的定义,也没正确导入,pickle找不到匹配的类,就会抛出AttributeError: Can't get attribute Employee。

解决办法

1. 正确导入类(推荐)

在读取shelve文件的新文件中,从原模块导入对应的类。假设原模块名为employee_models.py,新文件代码示例:

import shelve
# 从定义类的模块导入
from employee_models import Employee, Manager

with shelve.open('emp_db') as db:
    emp = db['emp1']
    print(emp.name)  # 正常访问属性

注意:确保原模块在Python的搜索路径中(比如和新文件同目录,或者添加到sys.path)。

2. 复制类定义到新文件(不推荐)

把Employee和Manager的完整代码复制到新文件中,但这种方式存在隐患——如果原模块的类定义修改,新文件的类和序列化时的类不一致,会导致反序列化失败或数据异常。

3. 手动指定类查找路径(特殊场景用)

如果类所在的模块路径发生了变更(比如原模块被重命名),可以自定义pickle的类查找逻辑,示例:

import shelve
import pickle

# 假设原类现在在new_module里,原模块名是old_module
class CustomUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        if module == 'old_module':
            module = 'new_module'
        return super().find_class(module, name)

with open('emp_db.dat', 'rb') as f:
    unpickler = CustomUnpickler(f)
    emp = unpickler.load()

内容的提问来源于stack exchange,提问作者RezDom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:18:24