本文记录在Windows上,使用PyCharm打包Python项目的操作。

1. 安装pyinstaller

打开PyCharm的设置,File --> Settings --> Python Interpreter,选择环境,点击+,搜索pyinstaller,点击安装。

2. 打包可执行文件

2.1 通过命令行打包

pyinstaller [options] script [script …] | specfile

在PyCharm,打开终端Terminal,输入命令pyinstaller命令,举例:

pyinstaller --icon icon.ico --name "芝麻酱"  -F main.py scrapyimages.py --add-data "fake_useragent_0.1.11.json;." --add-binary "C:\Anaconda3\Library\bin\mkl_intel_thread.1.dll;."

一些常用的选项:

-F, --onefile        打包成一个文件
-i, --icon            可执行程序的图标    
-n, --name            可执行程序文件名
-w, --noconsole        不显示控制台
-d, --debug            带调试信息
--add-data            添加依赖文件
--add-binary        添加库

PyInstaller更多用法见:Using PyInstaller — PyInstaller documentation。另:

执行pyinstaller options.. myscript.py,PyInstaller会创建一个规范说明文件name.spec(specification file)。事实上,运行pyinstaller的参数都在这里。因此,更建议直接在name.spec上修改,再打包。

2.2 通过规范说明文件打包

可以使用pyinstaller -F main.py生成main.spec,再编辑该文件:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['main.py', 'scrapyimages.py'],
             pathex=['D:\\workspace\\images_crawler\\src'],
             binaries=[('C:\\Anaconda3\\Library\\bin\\mkl_intel_thread.1.dll', '.')],
             datas=[('D:\\workspace\\images_crawler\\src\\fake_useragent_0.1.11.json', '.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             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=True , icon='icon.ico')

然后运行:

pyinstaller -F main.spec

关于规范说明文件说见:Using Spec Files — PyInstaller documentation

3. 遇到问题及解决

(1)Cannot load mkl_intel_thread.1.dll

打包完,双击.exe文件,控制台输出错误:

Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.1.dll

在电脑上找到mkl_intel_thread.1.dll的位置,C:\Anaconda3\Library\bin\mkl_intel_thread.1.dll,将该动态库添加到main.spec

(2)软件需要外部数据

我打包的这个应用,用到这个文件fake_useragent_0.1.11.json,打包时,不能用相对路径,原因是[1]:

运行可执行文件时,会先将可执行文件进行压缩再执行,压缩的位置在 /tmp 下。因此,被打包进去的数据文件在被解压的路径下,而程序是在运行的路径下搜索,即可执行文件的目录下,所以找不到数据文件。

因此,我这样处理:

from fake_useragent import UserAgent

#ua = UserAgent(path='./fake_useragent_0.1.11.json')

cur_dir = os.path.dirname(os.path.abspath(__file__))
ua = UserAgent(path = os.path.join(cur_dir, 'fake_useragent_0.1.11.json'))

(3)运行完退出

程序运行完,控制台就关了。想让控制台在程序执行完不关闭,方法很多。

  • 在main()函数末尾加上input('按任意键关闭窗口')
  • 在main()函数末尾加上os.system('pause')
  • 打开cmd,运行可执行文件

(4)程序运行一会,退出,没有错误信息

我将打包好的可执行文件放到其他电脑运行,双击后,运行一会,就退出,没有错误信息,也不是闪退。首先,加上-d选项,重新打包成带有调试信息的可执行文件。再次运行,得到如下信息:

C:\Users\admin\Desktop>芝麻酱.exe
[11884] PyInstaller Bootloader 3.x
[11884] LOADER: executable is C:\Users\admin\Desktop\芝麻酱.exe
...
[4100] LOADER: Running pyi_rth_pyqt5.py
[4100] LOADER: Running pyi_rth_mplconfig.py
[4100] LOADER: Running pyi_rth_mpldata.py
[4100] LOADER: Running pyi_rth_certifi.py
[4100] LOADER: Running pyi_rth__tkinter.py
[4100] LOADER: Running main.py
[11884] LOADER: Back to parent (RC: -1066598274)
[11884] LOADER: Doing cleanup
[11884] LOADER: Freeing archive status for C:\Users\admin\Desktop\芝麻酱.exe

我估计问题出在tkinter包,搜索了下,说是缺少libiomp5md.dll[2]。在Anaconda目录搜索该文件,找到C:\Anaconda3\Library\bin\libiomp5md.dll,将libiomp5md.dll拷贝到main.py同一个目录下,并添加到spec文件的datas中,重新打包文件。

datas=[('libiomp5md.dll', '.')]

遗憾的是,问题依旧,知道方法的,烦请告知。

(5)Could not find the matplotlib data files

用Pyinstaller打包时,报错误“Could not find the matplotlib data files”。

image-20220703123848494

这是因为matplotlib从3.2开始,mpl-data被分离出去了,安装离3.2之前最近的版本3.1.3

$ pip install matplotlib==3.1.3
Collecting matplotlib==3.1.3
  Downloading matplotlib-3.1.3-cp38-cp38-win_amd64.whl (9.1 MB)
     |████████████████████████████████| 9.1 MB 6.4 MB/s
Requirement already satisfied: python-dateutil>=2.1 in c:\anaconda3\lib\site-packages (from matplotlib==3.1.3) (2.8.1)
Requirement already satisfied: cycler>=0.10 in c:\anaconda3\lib\site-packages (from matplotlib==3.1.3) (0.10.0)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in c:\anaconda3\lib\site-packages (from matplotlib==3.1.3) (2.4.7)
Requirement already satisfied: kiwisolver>=1.0.1 in c:\anaconda3\lib\site-packages (from matplotlib==3.1.3) (1.3.1)
Requirement already satisfied: numpy>=1.11 in c:\anaconda3\lib\site-packages (from matplotlib==3.1.3) (1.20.1)
Requirement already satisfied: six in c:\anaconda3\lib\site-packages (from cycler>=0.10->matplotlib==3.1.3) (1.15.0)
Installing collected packages: matplotlib
  Attempting uninstall: matplotlib
    Found existing installation: matplotlib 3.5.2
    Uninstalling matplotlib-3.5.2:
      Successfully uninstalled matplotlib-3.5.2
Successfully installed matplotlib-3.1.3

参考资料:

[1] Pyinstaller将外部数据文件打包到可执行文件中(onefolder or onefile)教程_m0_37477175的博客-CSDN博客

[2] python - PyInstaller .exe file terminates early without an error message - Stack Overflow

本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-07-03 12:41

results matching ""

    No results matching ""