使用cx_Freeze打包Python应用后出现keras模块加载失败问题求助
问题描述
我用cx_Freeze打包了名为AI Hound的Python应用,启动后触发ModuleNotFoundError,提示找不到keras模块。打包生成的build文件夹中存在tensorflow/python/keras目录,但程序仍尝试调用本地Python环境和项目venv中的文件。
报错信息
ERROR:root:UNEXPECTED ERROR: Traceback (most recent call last): File "ai_hound.py", line 78, in run File "ai_hound.py", line 51, in load_models File "D:\PyPrj\FP2\venv\lib\site-packages\tensorflow\python\util\lazy_loader.py", line 58, in __getattr__ module = self._load() File "D:\PyPrj\PF2\venv\lib\site-packages\tensorflow\python\util\lazy_loader.py", line 41, in _load module = importlib.import_module(self.__name__) File "C:\Users\PGD\AppData\Local\Programs\Python\Python39\lib\importlib\__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1030, in _gcd_import File "<frozen importlib._bootstrap>", line 1007, in _find_and_load File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed File "<frozen importlib._bootstrap>", line 1030, in _gcd_import File "<frozen importlib._bootstrap>", line 1007, in _find_and_load File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed File "<frozen importlib._bootstrap>", line 1030, in _gcd_import File "<frozen importlib._bootstrap>", line 1007, in _find_and_load File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed File "<frozen importlib._bootstrap>", line 1030, in _gcd_import File "<frozen importlib._bootstrap>", line 1007, in _find_and_load File "<frozen importlib._bootstrap>", line 984, in _find_and_load_unlocked ModuleNotFoundError: No module named 'keras'
setup.py配置
import sys, os from cx_Freeze import setup, Executable PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__)) os.environ['TCL_LIBRARA'] = os.path.join(PYTHON_INSTALL_DIR, "tcl", "tcl8.6") os.environ['TK_LIBRARA'] = os.path.join(PYTHON_INSTALL_DIR, "tcl", "tk8.6") build_exe_options = {"packages": ["time", "sys", "os", "base64", "cv2", "logging", "codecs", "shutil", "zipfile", "fitz", "pandas", "numpy", "tensorflow", "PIL", "io", "tkinter"], "includes": ["tkinter", "tensorflow"], "include_files": [ os.path.join(PYTHON_INSTALL_DIR, "DLLs", "tk86t.dll"), os.path.join(PYTHON_INSTALL_DIR, "DLLs", "tcl86t.dll") ], "excludes": []} base = None if sys.platform == "win32": base = "Win32GUI" setup( name = "AI Hound", version = "1.0.1", description = "AI Hound", options = {"build_exe": build_exe_options}, executables = [Executable("ai_hound.py", icon="icon.ico", base = base)] )
问题原因分析
- Keras导入路径不匹配:TensorFlow集成的Keras是
tensorflow.keras,而非独立的keras模块。如果代码中直接用import keras,会尝试寻找独立安装的Keras包,但打包时仅包含了tensorflow,未处理该导入映射。 - cx_Freeze未识别懒加载机制:报错栈显示问题来自
tensorflow.python.util.lazy_loader,cx_Freeze可能无法识别TensorFlow的懒加载逻辑,导致tensorflow.keras相关模块未被正确打包或路径映射错误。 - 本地环境路径残留:打包后的程序仍调用本地venv路径,说明cx_Freeze未完全隔离环境,可能是部分硬编码路径或懒加载模块的路径解析未被正确处理。
解决建议
1. 修改代码中的Keras导入方式
将代码中所有import keras改为from tensorflow import keras或import tensorflow.keras as keras,确保使用TensorFlow内置的Keras模块,避免寻找独立包。
2. 调整setup.py配置,强制包含相关模块
在build_exe_options中添加tensorflow.keras到packages或includes列表,同时指定namespace_packages处理TensorFlow的命名空间:
build_exe_options = { "packages": ["time", "sys", "os", "base64", "cv2", "logging", "codecs", "shutil", "zipfile", "fitz", "pandas", "numpy", "tensorflow", "tensorflow.keras", "PIL", "io", "tkinter"], "includes": ["tkinter", "tensorflow", "tensorflow.keras", "tensorflow.keras.layers", "tensorflow.keras.models"], # 根据实际使用的子模块补充 "include_files": [os.path.join(PYTHON_INSTALL_DIR, "DLLs", "tk86t.dll"), os.path.join(PYTHON_INSTALL_DIR, "DLLs", "tcl86t.dll")], "namespace_packages": ["tensorflow"], "excludes": [] }
3. 修复环境变量拼写错误
setup.py中TCL_LIBRARA和TK_LIBRARA存在拼写错误,应为TCL_LIBRARY和TK_LIBRARY,这可能导致打包时依赖处理异常:
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, "tcl", "tcl8.6") os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, "tcl", "tk8.6")
4. 清理旧build目录后重新打包
删除原有的build和dist目录,重新运行打包命令,避免旧文件干扰:
rm -r build dist python setup.py build
5. 手动添加打包后的TensorFlow路径到sys.path
如果上述方法无效,可在代码启动时手动添加路径:
import sys, os if getattr(sys, 'frozen', False): # 获取打包后的程序目录 app_path = os.path.dirname(sys.executable) # 添加tensorflow路径到sys.path tensorflow_path = os.path.join(app_path, 'tensorflow') if tensorflow_path not in sys.path: sys.path.insert(0, tensorflow_path)
内容的提问来源于stack exchange,提问作者Markus Bauer
相关产品推荐
相关产品推荐

