使用Pickle加载变量时触发AttributeError: Can't get attribute 'Wishart'错误
解决Pickle加载时的AttributeError: Can't get attribute 'Wishart'问题
Hey,这个错误我见得挺多的,本质是pickle的特性导致的——它保存的是对象的引用,而不是完整的类定义,所以加载时Python得能找到当初创建这个对象的那个类才行。咱们一步步来解决:
问题根源
你用pickle保存Wishart实例的时候,这个类肯定是在某个地方定义的,但现在加载的时候,Python在当前运行的__main__模块(也就是你的app.py)里找不到这个类的定义了,所以才抛出这个AttributeError。
可行的解决办法
1. 先确保Wishart类在当前模块可用
如果当初保存实例时,Wishart就是在app.py里定义的,那你要保证在执行pickle.load()之前,这个类的定义已经被加载到当前模块中:
# 先定义或者导入Wishart类,要和保存时的类定义完全一致 class Wishart: # 这里放你原来的类代码,包括所有属性和方法 pass # 然后再执行加载操作(用with语句更安全,能自动关闭文件) import pickle with open('simpanan/priors', 'rb') as last_priors_file: priors = pickle.load(last_priors_file)
2. 把Wishart类放到独立模块(推荐方案)
这是最规范的做法,把类定义移到一个单独的模块,比如distributions.py,不管保存还是加载都从这个模块导入类:
- 保存时的代码示例:
from distributions import Wishart import pickle # 创建实例并保存 my_wishart = Wishart() with open('simpanan/priors', 'wb') as f: pickle.dump(my_wishart, f)
- 加载时的代码示例:
from distributions import Wishart # 必须先导入这个类 import pickle with open('simpanan/priors', 'rb') as f: priors = pickle.load(f)
这样不管你在哪加载这个pickle文件,只要正确导入这个模块,就能找到类定义,不会再出问题。
3. 临时给__main__模块映射类
如果没法修改之前的保存逻辑,也可以临时把Wishart类注册到__main__模块的命名空间里:
import pickle # 从当初定义Wishart类的那个模块导入它 from your_module import Wishart # 把类添加到__main__模块中 import __main__ __main__.Wishart = Wishart # 现在再加载就没问题了 with open('simpanan/priors', 'rb') as last_priors_file: priors = pickle.load(last_priors_file)
内容的提问来源于stack exchange,提问作者Anugrah Dwiatmaja Putra
相关产品推荐
相关产品推荐

