跳转至

使用 Pyinstaller 打包 exe 应用程序

pyinstaller 官方文档

一、 环境准备

为了减小打包后的文件体积并避免依赖冲突,强烈建议在虚拟环境中进行打包。

# 1. 创建虚拟环境
python -m venv .venv

# 2. 激活虚拟环境
# Windows:
.venv\Scripts\activate
# Linux/macOS:
source .venv/bin/activate

# 3. 安装必要的依赖和 PyInstaller
pip install pyinstaller

二、 快速开始

对于大多数项目,直接通过命令行参数即可快速完成打包。

1. 常用命令示例

场景 命令
单文件打包 pyinstaller -F main.py
隐藏控制台 (GUI程序) pyinstaller -F -w main.py
自定义图标 pyinstaller -F -i favicon.ico main.py
清理缓存并打包 pyinstaller --clean -F main.py

2. 常用参数说明

  • -F, --onefile: 将程序及其依赖包打包成一个独立的 .exe 文件
  • -D, --onedir: 打包成包含 .exe 和依赖库的文件夹
  • -w, --windowed: 打包 GUI 程序时使用,运行时不显示黑色控制台窗口
  • -i, --icon: 指定生成的程序图标(.ico 格式)
  • -n, --name: 指定生成的 .exe 文件名,默认为脚本基本名称

三、 打包模式对比

特性 单文件 (-F) 文件夹 (-D)
优点 方便分发,只有一个文件 启动速度快,方便调试和部分更新代码
缺点 运行速度较慢 (需解压到临时目录) 分发不便,需发送整个文件夹或压缩包
资源路径 需注意 sys._MEIPASS 路径问题 通常可直接使用相对路径

四、 进阶:使用 .spec 规范文件

涉及复杂依赖或需要精细控制打包过程时,建议使用 .spec 文件。

1. 生成规范文件

pyi-makespec -F main.py

2. 配置文件说明

生成 main.spec 后,可对以下关键部分进行定制:

main.spec
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None # 加密密钥

# Analysis类的实例,要求传入各种脚本用于分析程序的导入和依赖。
a = Analysis(
    # 需要打包的代码文件,是一个列表
    ['main.py'],

    pathex=[],

    # 脚本所需的二进制文件( DLL、动态库、共享对象文件等) [tuple(src:str, dst:str)]
    # src:指定当前系统中的一个或多个文件 dst: 在运行时包含这些文件的文件夹的名称
    binaries=[],

    # 应用程序中包含的数据文件(图片等) [tuple(src:str, dst:str)]
    datas=[],

    # 指定脚本中需要隐式导入的模块,比如在__import__、imp.find_module()等语句中导入的模块
    # 这些方法导入的模块 PyInstaller 无法进行分析,需要手动指定导入
    hiddenimports=[],

    # 指定额外hook文件(可以是py文件)的查找路径,这些文件的作用是在PyInstaller运行时改变
    # 一些Python或者其他库原有的函数或者变量的执行逻辑(并不会改变这些库本身的代码),以便能顺利的打包完成
    hookspath=[],
    hooksconfig={},

    # 指定自定义的运行时hook文件路径(可以是py文件),在打好包的exe程序中,在运行这个exe程序时
    # 指定的hook文件会在所有代码和模块之前运行,包括main文件,以满足一些运行环境的特殊要求
    runtime_hooks=[],

    # 指定可以被忽略的可选的模块或包,因为某些模块只是PyInstaller根据自身的逻辑去查找的
    # 这些模块对于exe程序本身并没有用到,但是在日志中还是会提示“module not found”
    # 这种日志可以不用管,或者使用这个参数选项来指定不用导入
    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 = EXE(
    ...
    console=True, # 设置是否显示命令行窗口
    icon="/img.ico" # 设置程序图标路径
)

3. 从规范文件构建

pyinstaller --clean main.spec --noconfirm

五、 FAQ

1. 打包文件过大

请务必在虚拟环境中执行打包命令,确保 PyInstaller 仅打包当前项目所需的依赖。

2. 打包后提示找不到资源文件

原因: 单文件打包运行后会解压到系统临时目录。若代码使用 os.getcwd() 等访问资源,会因运行目录与解压目录不一致而报错。 解决: 建议查阅官方文档 pyinstaller 运行时信息 获取正确的路径处理方式。

打包文件示例参考 (GitHub)