Streamlit加载pickle自定义对象遇ModuleNotFoundError的原因与解决
1. Python运行环境不一致
直接用python命令运行脚本时,使用的是当前终端激活的Python环境(比如虚拟环境或系统默认环境);而通过Streamlit运行时,可能调用了不同的Python环境(比如系统全局环境、另一个虚拟环境,或者Streamlit自身绑定的环境)。如果custom_library只安装在直接运行的环境里,Streamlit的环境找不到这个库,就会报错。
2. Pickle反序列化的依赖特性
Pickle在加载对象时,需要能找到该对象所属类的定义文件——也就是custom_library必须在当前运行环境的**Python搜索路径(sys.path)**中。就算两个环境是同一个,如果custom_library所在的目录没被添加到Streamlit运行时的sys.path里,也会触发找不到模块的错误。
统一运行环境:
在脚本开头添加以下代码,分别用python script.py和streamlit run script.py运行,查看输出的Python可执行文件路径:import sys print(sys.executable)如果路径不同,切换到同一个环境(比如激活对应的虚拟环境),然后用该环境的
pip安装custom_library。手动添加模块路径到sys.path:
在加载pickle之前,把custom_library所在的目录添加到Python搜索路径中。假设custom_library位于项目根目录下,修改脚本如下:import sys from pathlib import Path main_path = Path(__file__).parent.parent # 假设custom_library在main_path的子目录里,根据实际路径调整 lib_path = main_path / "custom_library" sys.path.append(str(lib_path)) # 之后再加载pickle import pickle file_path = main_path / 'out' / 'data.pickle' with open(file_path, 'rb') as file: pf = pickle.load(file)安装自定义库到环境:
如果custom_library是你自己编写的,进入该库的根目录(包含setup.py或pyproject.toml的目录),执行以下命令将其安装到当前环境(开发模式,修改代码后无需重新安装):pip install -e .这样不管是直接用Python还是Streamlit运行,都能找到这个库。
重新生成Pickle文件:
如果Pickle文件是在另一个环境生成的,可能类的导入路径存在差异。建议在当前要运行的环境中,重新用custom_library生成Pickle文件,再加载使用。
内容的提问来源于stack exchange,提问作者steam1901

