可执行文件生成


安装工具包

将.py文件打包成可执行文件需要下载第三方工具包: pyinstaller

安装方法:
在自己的python环境中使用pip命令安装pyinstaller

pip install pyinstaller

注意事项:

  • pyinstaller在windows环境下生成的是能在windows中使用的可执行文件, 在mac环境下生成的是能mac中使用的可执行文件。因此需要针对可执行文件的运行实际使用环境, 生成对应的可执行文件。
  • 要配合虚拟环境进行打包。因为打包时, 需要将你使用的第三方库、Python解释器等一并打包。

开发流程:
以windows开发mac端为例

1. 在window系统上创建开发用的虚拟环境
2. 开发...
3. 开发完毕 
   pip freeze > requirements.txt 保存环境中依赖包信息
   
4. 打开mac虚拟机
5. 创建虚拟环境
6. 安装依赖包
   pip install -r requirements.txt
7. 安装pyinstaller
   pip install pyinstaller
8. 将程序打包成mac端的可执行文件
   pyinstaller -F xxxx
  
如果不用跨系统, 就不需要用虚拟机, 开发完成后直接打包即可

多文件打包

优点:

  • 运行速度比单文件打包快

缺点:

  • 打包完会产生除可执行文件外和多个依赖文件, 必须将所有文件放在一起, 可执行文件才能正常使用

打包命令:

pyinstaller -D xx.py
  • xx.py为你要打包的python文件名
    操作展示
    打包成功显示

生成文件说明:
打包完成后会生成如下三个文件
生成文件

  • build文件夹: 没用, 是打包过程中产生的中间文件, 可直接删除。
  • dist文件夹: 用于存放打包好的文件, 将内部的文件夹压缩(见下图“压缩”)发给客户即可, 客户只需解压后双击文件夹内的.exe文件(见下图“可执行文件”)即可。
    压缩
    可执行文件
  • .spec文件: 为打包时生成的配置文件, 也可以删除

单文件打包

优点:

  • 只会生成一个可执行文件, 没有多余文件生成, 方便使用

缺点:

  • 程序执行速度相比多文件打包较慢

打包命令:

pyinstaller -F xx.py
  • xx.py为你要打包的python文件名
    操作展示
    打包成功显示

生成文件说明:
打包完成后会生成如下三个文件
生成文件

  • build文件夹: 没用, 是打包过程中产生的中间文件, 可直接删除。
  • dist文件夹: 里面只有一个打包好的可执行文件, 双击即可运行, 将其直接发给客户即可。
    可执行文件
  • .spec文件: 为打包时生成的配置文件, 也可以删除

报错程序错误检查

  1. 若原本的python文件有报错, 则打包成的可执行文件无法正常运行, 会直接关闭。
  2. 若想查看报错类型, 可以打开系统的cmd终端, 将可执行文件拖进中端(或输入exe文件路径)并回车运行即可。
    • 若程序正常, 则显示运行结果
      程序正确
      显示结果
    • 若程序错误, 则显示报错
      程序错误
      显示报错

可执行文件命名

使用pyinstaller -D xx.pypyinstaller -F xx.py打包文件生成的可执行文件默认以被打包的python文件的名称命名。

  • 若想更改可执行文件的名字, 需要再加上 -n 你想为可执行文件取的名字 。命令如下:
    pyinstaller -D xx.py -n 你想为可执行文件取的名字
    pyinstaller -F xx.py -n 你想为可执行文件取的名字
    

实操展示:
以’单文件打包’为例, 将可执行文件命名为”你好世界“
命令行操作展示
生成结果展示

打包路径问题

如果你打包的Python程序需要调用其他文件, 请在python文件中使用以下方法设置被调用文件的路径。 且在运行可执行文件时, 被调用的文件需与可执行文件放在同一路径下。

import os
import sys

BASE_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))

FILE_DIR = os.path.join(BASE_DIR, "你要打开的文件名")
  • 在之后代码中用BASE_DIR表示生成的可执行文件路径, 用FILE_DIR表示被调用文件路径

如需深入了解理由, 可以参考此视频

打包导入模块问题

  • 打包过程中, 会自动打包所有被调用的模块(包括被调用的模块中被调用的模块), 但在原文件存在但没被调用的模块不会被打包。

★★★ 但如果是通过动态导入的模块(如下代码), 则不会被打包, 在可执行文件运行时会报错。

import importlib

card = importlib.import_module("被动态导入的模块名")

解决方法:

  1. 先生成可执行文件
  2. 在.spec文件的hiddenimports添加动态调用的模块
    添加动态调用的模块
  3. 通过.spec生成新的可执行文件。
    • 切记: 是对.spec而不是对python文件生成
      以单文件打包为例
     pyinstaller -F spec文件名的文件名.spec
    

    添加动态调用的模块

如需深入了解理由, 可以参考此视频


  目录