深入解析:PyInstaller 完整使用教程

作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习
擅长领域:驱动开发,嵌入式软件开发,BSP开发
❄️作者主页:一个平凡而乐于分享的小比特的个人主页
✨收录专栏:Python,本专栏为记录项目中用到常用python库
欢迎大家点赞 收藏 ⭐ 加关注哦!

在这里插入图片描述

PyInstaller 完整使用教程

一、PyInstaller 简介

PyInstaller 是一个将 Python 程序打包成独立可执行文件的工具,支持 Windows、Linux、macOS 等操作系统。它分析 Python 代码,自动收集所有依赖项(包括隐藏导入),生成单文件或目录结构的可执行程序。

二、安装 PyInstaller

基础安装

pip install pyinstaller

升级到最新版本

pip install --upgrade pyinstaller

安装开发版本(不推荐生产环境)

pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip

三、快速开始

最简单的打包命令

# 基本打包(生成dist和build目录)
pyinstaller your_script.py
# 打包后会在 dist/your_script 目录中找到可执行文件

创建单文件程序(最常用)

pyinstaller --onefile your_script.py
# 生成单个独立的 .exe 文件

创建无控制台窗口的程序(GUI应用)

pyinstaller --onefile --windowed your_script.py
# 或
pyinstaller -F -w your_script.py

四、常用命令行参数详解

参数简写说明
--onefile-F打包成单个文件
--onedir-D打包成目录(默认)
--windowed-w不显示控制台窗口(GUI程序)
--console-c显示控制台窗口(默认)
--icon=<图标文件>-i设置程序图标
--name=<程序名>-n设置生成的可执行文件名
--clean清理临时文件
--noupx不使用 UPX 压缩
--upx-dir=<路径>指定 UPX 目录
--hidden-import=<模块>添加隐藏导入的模块
--add-data=<源:目标>添加数据文件
--add-binary=<源:目标>添加二进制文件
--paths=<路径>添加模块搜索路径
--debug启用调试模式
--strip剥离符号表(Linux/Mac)

五、实战示例

示例1:基础打包

# hello.py
import tkinter as tk
from tkinter import messagebox
def show_message():
messagebox.showinfo("Hello", "欢迎使用PyInstaller!")
if __name__ == "__main__":
root = tk.Tk()
root.title("示例程序")
root.geometry("300x200")
btn = tk.Button(root, text="点击我", command=show_message, font=("Arial", 14))
btn.pack(expand=True)
root.mainloop()

打包命令:

# 打包成单文件GUI程序
pyinstaller --onefile --windowed --icon=myicon.ico --name="MyApp" hello.py
# 打包成目录结构
pyinstaller --onedir --windowed hello.py

示例2:包含数据文件的项目

项目结构:

my_project/
├── main.py
├── config.json
├── images/
│   └── logo.png
└── data/
    └── database.db
# main.py
import os
import sys
import json
def resource_path(relative_path):
"""获取资源的绝对路径,支持开发环境和PyInstaller打包后"""
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
# 读取配置文件
config_path = resource_path('config.json')
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
print(f"应用名称: {config['app_name']}")

打包命令:

# 添加数据文件和目录
pyinstaller --onefile \
--add-data="config.json;." \
--add-data="images/logo.png;images" \
--add-data="data/database.db;data" \
main.py

注意:Windows 使用分号 ; 分隔,Linux/Mac 使用冒号 : 分隔

六、使用 .spec 文件进行高级配置

生成 .spec 文件

pyinstaller --onefile your_script.py
# 会自动生成 your_script.spec 文件

手动编辑 .spec 文件示例

# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['main.py'],  # 主程序文件
pathex=[],    # 额外搜索路径
binaries=[],  # 二进制文件
datas=[       # 数据文件
('config.json', '.'),
('images/*.png', 'images'),
('data/*.db', 'data')
],
hiddenimports=[  # 隐藏导入的模块
'pandas._libs.tslibs.np_datetime',
'sklearn.utils._weight_vector'
],
hookspath=[],   # 自定义hook路径
hooksconfig={}, # hooks配置
runtime_hooks=[], # 运行时hook
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='MyApplication',  # 程序名
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,  # 使用UPX压缩
upx_exclude=[],
runtime_tmpdir=None,
console=False,  # 不显示控制台
icon='myicon.ico',  # 图标
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

使用 .spec 文件打包

# 使用修改后的.spec文件打包
pyinstaller your_script.spec
# 清理后重新打包
pyinstaller --clean your_script.spec

七、处理常见问题

1. 解决隐藏导入问题

# 方法1:命令行指定
pyinstaller --onefile --hidden-import=模块名1 --hidden-import=模块名2 your_script.py
# 方法2:创建hook文件
# 在 hooks/ 目录下创建 hook-模块名.py

2. 解决动态导入问题

# 在代码中显式导入
import importlib
# 动态导入的模块需要在代码开头显式声明
import pandas
import numpy
import sklearn
# 或者在打包时添加
# --hidden-import=pandas --hidden-import=sklearn

3. 路径问题处理

import os
import sys
def get_resource_path(relative_path):
"""获取资源文件的正确路径"""
try:
# PyInstaller创建临时文件夹,将路径存储在_MEIPASS中
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
# 使用示例
icon_path = get_resource_path('images/icon.ico')

4. 减小可执行文件体积

# 使用UPX压缩(需要单独下载UPX)
# 1. 下载UPX: https://upx.github.io/
# 2. 指定UPX路径
pyinstaller --onefile --upx-dir=C:\upx your_script.py
# 排除不需要的模块
pyinstaller --onefile --exclude-module=matplotlib --exclude-module=scipy your_script.py

八、多平台打包

Windows 打包

# Windows 专用选项
pyinstaller --onefile --version-file=version.txt your_script.py
# version.txt 示例
VSVersionInfo(
ffi=FixedFileInfo(
filevers=(1, 0, 0, 0),
prodvers=(1, 0, 0, 0),
mask=0x3f,
flags=0x0,
OS=0x40004,
fileType=0x1,
subtype=0x0,
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'040904B0',
[StringStruct(u'CompanyName', u'我的公司'),
StringStruct(u'FileDescription', u'我的应用程序'),
StringStruct(u'FileVersion', u'1.0.0.0'),
StringStruct(u'InternalName', u'MyApp'),
StringStruct(u'LegalCopyright', u'Copyright © 2024'),
StringStruct(u'OriginalFilename', u'MyApp.exe'),
StringStruct(u'ProductName', u'我的产品'),
StringStruct(u'ProductVersion', u'1.0.0.0')])
]),
VarFileInfo([VarStruct(u'Translation', [0x409, 1200])])
]
)

Linux 打包

# 可能需要安装依赖
sudo apt-get install python3-dev
# 打包命令
pyinstaller --onefile your_script.py

macOS 打包

# 打包为.app应用
pyinstaller --windowed --name="MyApp" your_script.py
# 代码签名
pyinstaller --windowed --name="MyApp" \
--osx-bundle-identifier="com.company.app" \
your_script.py

九、最佳实践

1. 创建打包脚本

# build.bat (Windows)
@echo off
echo 正在清理旧文件...
rmdir /s /q build 2>nul
rmdir /s /q dist 2>nul
del *.spec 2>nul
echo 正在安装依赖...
pip install -r requirements.txt
echo 正在打包...
pyinstaller --onefile --windowed --icon=icon.ico --name="MyApp" main.py
echo 打包完成!程序在 dist 目录中。
pause
# build.sh (Linux/Mac)
#!/bin/bash
echo "正在清理旧文件..."
rm -rf build dist *.spec
echo "正在安装依赖..."
pip install -r requirements.txt
echo "正在打包..."
pyinstaller --onefile --windowed --icon=icon.ico --name="MyApp" main.py
echo "打包完成!程序在 dist 目录中。"

2. 创建虚拟环境打包

# 创建虚拟环境
python -m venv build_env
# Windows
build_env\Scripts\activate
# Linux/Mac
source build_env/bin/activate
# 安装依赖和PyInstaller
pip install -r requirements.txt
pip install pyinstaller
# 打包
pyinstaller --onefile your_script.py

3. 测试打包结果

# 在dist目录中运行
cd dist
./your_script  # Linux/Mac
.\your_script.exe  # Windows
# 检查依赖
# Windows: 使用 Dependency Walker
# Linux: ldd your_script

十、常见错误及解决方案

错误1: ModuleNotFoundError

解决方案

# 添加隐藏导入
pyinstaller --hidden-import=missing_module your_script.py

错误2: Failed to execute script

解决方案

# 重新打包并显示控制台查看错误
pyinstaller --onefile --console your_script.py
# 或使用调试模式
pyinstaller --debug your_script.py

错误3: 文件体积过大

解决方案

  1. 使用虚拟环境只安装必要包
  2. 使用UPX压缩
  3. 排除不必要的模块

错误4: 杀毒软件误报

解决方案

  1. 对程序进行代码签名
  2. 提交到杀毒软件厂商白名单
  3. 提供源代码证明无害

十一、高级技巧

1. 自定义引导程序

# 创建 runtime-hooks
# runtime-hooks/myhook.py
import sys
import os
# 在程序启动前执行的代码
sys.stdout = open(os.devnull, 'w')  # 禁用标准输出
pyinstaller --runtime-hook=runtime-hooks/myhook.py your_script.py

2. 打包多个脚本

# multi.spec
exe1 = EXE(pyz, ...)
exe2 = EXE(pyz, ...)
coll = COLLECT(exe1, exe2, ...)

3. 使用配置文件

# config.py
APP_NAME = "MyApp"
VERSION = "1.0.0"
ICON_PATH = "resources/icon.ico"
# build_config.py
import config
import subprocess
cmd = [
'pyinstaller',
'--onefile',
'--windowed',
f'--name={config.APP_NAME}',
f'--icon={config.ICON_PATH}',
'main.py'
]
subprocess.run(cmd)

总结

PyInstaller 是一个强大且灵活的工具,通过本教程你应该能够:

  1. ✅ 掌握基本打包命令
  2. ✅ 处理复杂的依赖关系
  3. ✅ 包含数据文件和资源
  4. ✅ 解决常见的打包问题
  5. ✅ 进行多平台打包

记住,最佳的学习方式是多实践,遇到问题时:

  1. 仔细阅读错误信息
  2. 使用 --debug 模式
  3. 查看官方文档:https://pyinstaller.org/
  4. 搜索 GitHub Issues
posted @ 2026-01-15 09:51  gccbuaa  阅读(86)  评论(0)    收藏  举报