Python脚本加载pickle文件中函数时遇AttributeError问题求助
问题分析与解决办法
核心原因
Pickle序列化函数时,并不会保存函数的完整代码,仅记录函数的模块路径和名称。加载时,Python会尝试从当前运行环境的对应模块中查找同名函数。你遇到的错误本质是:加载时__main__模块(即你的app.py)中找不到get_book_recommendations函数。而Colab能正常运行是因为:
- 在Colab中,你是在同一个会话里先定义函数、再保存pickle、最后加载,此时
__main__模块中已经存在该函数,pickle可以直接找到; - 本地运行时,要么加载pickle的代码执行在函数定义之前,要么函数所在模块与保存时的模块路径不匹配。
解决办法
办法1:调整代码执行顺序,确保加载前函数已定义
将get_book_recommendations函数的定义放在加载pickle的代码之前,保证加载时__main__模块中存在该函数:
import pickle # 先定义函数,再执行加载操作 def get_book_recommendations(book_title): # 此处是你的函数实现代码 pass with open('book_recommendations.pkl', 'rb') as file: get_book_recommendations = pickle.load(file) cosine_sim_reduced_sample = pickle.load(file) df2 = pickle.load(file) tfidf_vectorizer = pickle.load(file) svd = pickle.load(file) book_title = "memior" recommendations = get_book_recommendations(book_title) print(recommendations)
办法2:将函数封装到独立模块中(推荐)
把函数放到单独的模块文件中,保存和加载时统一从该模块引用,避免模块路径不匹配的问题:
- 创建
rec_utils.py文件,写入函数定义:
def get_book_recommendations(book_title): # 函数实现代码 pass
- 在Colab中保存pickle时,从该模块导入函数后再保存:
import pickle from rec_utils import get_book_recommendations # 执行保存操作 with open('book_recommendations.pkl', 'wb') as file: pickle.dump(get_book_recommendations, file) # 依次保存其他对象...
- 本地加载时,先导入该模块再加载pickle:
import pickle from rec_utils import get_book_recommendations with open('book_recommendations.pkl', 'rb') as file: get_book_recommendations = pickle.load(file) # 加载其他对象...
办法3:自定义Unpickler手动映射函数
如果不想调整模块结构,可以自定义Unpickler,强制让pickle从当前模块中获取目标函数:
import pickle # 先定义函数 def get_book_recommendations(book_title): # 函数实现代码 pass class CustomUnpickler(pickle.Unpickler): def find_class(self, module, name): # 当pickle尝试从__main__模块找目标函数时,返回本地定义的函数 if module == '__main__' and name == 'get_book_recommendations': return get_book_recommendations return super().find_class(module, name) with open('book_recommendations.pkl', 'rb') as file: unpickler = CustomUnpickler(file) get_book_recommendations = unpickler.load() # 其他对象用同一个unpickler加载 cosine_sim_reduced_sample = unpickler.load() df2 = unpickler.load() tfidf_vectorizer = unpickler.load() svd = unpickler.load() book_title = "memior" recommendations = get_book_recommendations(book_title) print(recommendations)
内容的提问来源于stack exchange,提问作者Airo
相关产品推荐
相关产品推荐

