python打包numpy和pandas报错-numpy: Error importing numpy: you should not try to import numpy from its source directory
在使用numpy2.3.2版本和python3.12版本时,打包一直报错
numpy: Error importing numpy: you should not try to import numpy from its source directory;
please exit the numpy source tree, and relaunch your python interpreter from there.
网上很多说是版本不匹配的问题,但是都没说这两个版本是否匹配。
通过PyInstaller 的钩子(hooks)来精确地收集 numpy 和 pandas 的所有动态链接库和数据文件。
修改 .spec 文件,强制收集所有必需的二进制文件:
# -*- mode: python ; coding: utf-8 -*- from PyInstaller.utils.hooks import collect_all, collect_data_files, collect_dynamic_libs block_cipher = None # --- 关键修改:为 numpy 和 pandas 收集所有文件 --- datas_n, binaries_n, hiddenimports_n = collect_all('numpy') datas_p, binaries_p, hiddenimports_p = collect_all('pandas') a = Analysis( ['watermark_tool.py'], pathex=[], # --- 关键修改:合并二进制文件 --- binaries=binaries_n + binaries_p, # --- 关键修改:合并数据文件 --- datas=[ ('示例数据.xlsx', '.'), *datas_n, # numpy 的数据文件 *datas_p, # pandas 的数据文件 ], # --- 关键修改:合并隐藏导入 --- hiddenimports=list(set( [ 'numpy', 'pandas', 'PIL', 'PIL.Image', 'PIL.ImageFont', 'PIL.ImageDraw', 'openpyxl', 'tkinter', 'tkinter.ttk', 'tkinter.messagebox', 'tkinter.filedialog', 'json', 'datetime', 'threading', 'platform', 'os', 'sys', ] + hiddenimports_n + hiddenimports_p # 添加 numpy 和 pandas 的隐藏导入 )), hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[ 'matplotlib', 'scipy', 'PyQt5', 'PyQt6', 'PySide2', 'PySide6', ], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='水印工具', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=False, # 设置为 False 以隐藏控制台窗口 disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, )
打包日志非常长,但是可以看到大量的如下分析行
INFO: Analyzing hidden import 'pandas.tests.tseries.offsets.test_business_day' INFO: Analyzing hidden import 'pandas.tests.series.test_arithmetic' INFO: Analyzing hidden import 'pandas.tests.plotting.frame.test_frame_subplots' ... INFO: Analyzing hidden import 'numpy.lib.tests.test_polynomial' INFO: Analyzing hidden import 'numpy.polynomial.tests.test_classes' ...
这表明 PyInstaller 正在尝试分析并打包 pandas 和 numpy 库中所有的测试模块(pandas.tests.* 和 numpy.*.tests.*)。这些测试模块通常依赖于 pytest 等测试框架,而这些框架在您的生产环境中并未安装,因此 PyInstaller 会抛出 ModuleNotFoundError: No module named 'pytest' 的警告。
更重要的是,这些测试模块是完全不需要打包到最终的生产应用程序中的。它们不仅体积庞大,而且会引入不必要的依赖和潜在的冲突,这就是导致最终的可执行文件在运行时无法正确加载 numpy 核心库的根本原因。
解决方案:在 .spec 文件中排除测试模块,excludes 参数修改为如下内容:
excludes=[ 'matplotlib', 'scipy', 'PyQt5', 'PyQt6', 'PySide2', 'PySide6', # --- 关键添加:排除测试模块 --- 'pytest', # 排除 pytest 本身 'unittest', # 可选,排除标准库 unittest,进一步减小体积 'pandas.tests', # 排除所有 pandas 测试 'numpy.testing', # 排除 numpy 的测试工具 'numpy._pytesttester', # 排除 numpy 的 pytest 测试器 'numpy.f2py.tests', # 排除 f2py 测试 'numpy.core.tests', # 排除核心测试 'numpy.lib.tests', # 排除 lib 测试 'numpy.linalg.tests', # 排除线性代数测试 'numpy.ma.tests', # 排除 masked array 测试 'numpy.matrixlib.tests', # 排除 matrix 测试 'numpy.polynomial.tests', # 排除多项式测试 'numpy.random.tests', # 排除随机数测试 'numpy.fft.tests', # 排除傅里叶变换测试 'numpy.typing.tests', # 排除类型提示测试 ],
再次打包即可,当然可以直接就添加test排除,hook是为了找到报错原因。
浙公网安备 33010602011771号