如何解决PyInstaller打包时出现No module named 'sklearn'的报错
sklearn打包失败原因
sklearn(scikit-learn)的架构存在两个特性,会导致PyInstaller默认静态依赖扫描失效:
- sklearn大量使用*延迟加载(懒加载)*机制,大量子模块仅在运行时被动态导入,不会被PyInstaller的静态扫描识别
- 官方PyInstaller安装包默认没有内置sklearn对应的预定义hook,不会主动收集sklearn的全量依赖
解决方案
方法1:临时添加隐藏导入(适合快速测试)
直接在打包命令中通过--hidden-import参数手动指定缺失的模块,你当前报错首先缺失sklearn主包和mixture子模块,先执行以下打包命令:
pyinstaller --hidden-import sklearn --hidden-import sklearn.mixture main.py
如果运行exe后仍报其他sklearn子模块缺失,按照报错提示的模块名,继续追加--hidden-import 模块名参数即可。
方法2:自定义hook文件(适合长期复用)
确定hook文件名
PyInstaller的hook文件遵循固定命名规则:hook-<导入模块名>.py,因此你需要创建的sklearn hook文件名为hook-sklearn.py。
编写hook内容
新建hook-sklearn.py文件,填入以下内容即可覆盖绝大多数sklearn打包场景:
from PyInstaller.utils.hooks import collect_submodules, collect_data_files # 收集sklearn下所有子模块,覆盖动态导入的依赖 hiddenimports = collect_submodules('sklearn') # 收集sklearn运行所需的配置、数据等非py资源文件 datas = collect_data_files('sklearn')
调用hook的两种方式
- 临时调用:打包时添加
--additional-hooks-dir参数,指向hook-sklearn.py所在的目录即可,示例命令:pyinstaller --additional-hooks-dir ./hook文件存放目录 main.py - 全局复用:将
hook-sklearn.py直接放入你找到的\Programs\Python\Python38\Lib\site-packages\PyInstaller\hooks目录,之后所有涉及sklearn的打包任务都会自动调用这个hook,无需额外加参数。
PyInstaller hook通用编写规则
- 文件名必须严格遵循
hook-<模块导入名>.py格式,模块名和代码中import后的名称完全一致 - 核心配置变量:
hiddenimports:列表类型,存放所有需要额外导入的模块全路径名,collect_submodules('包名')工具可以一键收集指定包下的所有子模块datas:列表类型,存放需要一起打包的非py资源文件路径,collect_data_files('包名')工具可以一键收集指定包下的所有资源文件
内容的提问来源于stack exchange,提问作者msax
相关产品推荐
相关产品推荐

