cx_freeze打包PyQt4应用遇sklearn模块导入错误求助
兄弟,我之前踩过cx_freeze打包PyQt+sklearn应用的坑,你的问题我太熟悉了!给你捋捋问题根源和靠谱的解决办法:
问题根源拆解
你碰到的第一个No Module Found错误,本质是cx_freeze打包时遗漏了multiprocessing.pool模块,而不是sklearn源码写错了(哦对了,你说的multprocessing其实是拼写错误,正确模块名是multiprocessing,多了个'r')。你手动修改sklearn的导入语句虽然暂时消了报错,但破坏了joblib的内部依赖逻辑,自然会引出新问题——绝对不要改第三方库的源码,这是饮鸩止渴的做法!
正确解决方案
从cx_freeze的配置和依赖版本入手,彻底解决问题:
1. 修正cx_freeze的打包配置
在你的setup.py里,强制指定要包含的依赖模块,确保cx_freeze不会漏掉关键部分:
from cx_Freeze import setup, Executable # 定义你的应用执行文件 app_target = Executable( script="你的主程序文件名.py", base="Win32GUI" # PyQt4桌面应用必须加这个,否则会弹出控制台窗口 ) setup( name="你的应用名称", version="1.0", description="应用描述", executables=[app_target], options={ "build_exe": { # 明确列出需要打包的包 "packages": ["multiprocessing", "sklearn", "joblib"], # 强制包含容易被遗漏的子模块 "includes": ["multiprocessing.pool"], # 如果有其他资源文件需要打包,在这里添加 "include_files": [] } } )
2. 升级sklearn和joblib版本
旧版本的joblib(被sklearn依赖)偶尔会有导入路径的小bug,升级到稳定版就能解决:
pip install --upgrade scikit-learn joblib
3. 添加multiprocessing的冻结支持
在你的应用入口文件最开头,加上这段代码,确保Windows下multiprocessing能正常工作:
import multiprocessing if __name__ == "__main__": # 必须加这个,cx_freeze打包后multiprocessing才能正常启动子进程 multiprocessing.freeze_support() # 然后启动你的PyQt4应用 from your_app_module import main_window main_window().exec_()
4. 恢复被修改的sklearn源码
先把你改的sklearn/externals/joblib/pool.py文件改回原来的导入语句(from multiprocessing.pool import Pool),然后用上面的配置重新打包,就能避免后续的新问题了。
内容的提问来源于stack exchange,提问作者sketchball
相关产品推荐
相关产品推荐

