Python 代码打包成可执行文件(exe)实战指南
概述
在开发完一个小项目后,通常需要将代码发布给他人使用。直接提供源码需要用户安装运行环境,而将代码打包成独立的可执行文件(如 Windows 下的 exe)则能简化部署流程。PyInstaller 是目前最流行的 Python 打包工具之一,它可以将 Python 脚本转换为单个可执行文件或目录,支持跨平台。
介绍使用 PyInstaller 将 Python 脚本转换为独立可执行文件的两种主要方法。涵盖命令行直接打包与 Spec 配置文件打包的适用场景及操作步骤。详细解析了 build 与 dist 文件夹的作用,Spec 文件中 Analysis、PYZ、EXE、COLLECT 类的使用细节,以及处理资源文件路径的方法。同时总结了打包失败常见原因如编码问题、路径含中文等,并提供了解决方案与优化建议。

在开发完一个小项目后,通常需要将代码发布给他人使用。直接提供源码需要用户安装运行环境,而将代码打包成独立的可执行文件(如 Windows 下的 exe)则能简化部署流程。PyInstaller 是目前最流行的 Python 打包工具之一,它可以将 Python 脚本转换为单个可执行文件或目录,支持跨平台。
除了 PyInstaller,还有其他工具可供选择:
本文重点介绍 PyInstaller 的使用方法及常见问题处理。
首先确保已安装 Python 环境,并通过 pip 安装 PyInstaller:
pip install pyinstaller
命令行打包适用于简单项目,无需复杂配置。假设有一个名为 demo.py 的文件:
# demo.py
import os
path = os.getcwd()
print(f'当前文件路径:{path}')
os.system('pause')
在终端进入文件所在目录,执行以下命令:
pyinstaller -F demo.py
-F / -D:-F 生成单个可执行文件;-D 生成一个目录(包含多个文件)。-w / -c:-w 去掉命令行弹窗(窗口模式);-c 显示命令行弹窗(控制台模式)。-i icon.ico:指定 exe 显示图标。--onefile:等同于 -F。--onedir:等同于 -D。打包完成后,会在原目录下生成两个文件夹:
点击 dist 目录下的 demo.exe,若弹出小黑窗并显示路径信息,即表示打包成功。
Spec 文件打包适用于大规模、复杂项目,或需要自定义配置、频繁重复打包的场景。例如需要一起打包数据文件、动态链接库,或添加运行时选项时。
PackingExe
├── core
│ ├── __init__.py
│ └── dict.txt
└── demo.py
当 exe 运行时,会生成临时文件夹,除代码外的数据资源需要通过 sys._MEIPASS 访问。建议封装获取资源路径的函数:
import sys
import os
def resource_path(relative_path):
""" 运行 exe 时获取资源文件的绝对路径"""
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
def main():
print(f'当前文件路径:{os.getcwd()}')
abs_path = resource_path('core/dict.txt')
with open(abs_path, 'r', encoding='utf-8') as file:
content = file.readline()
print(content)
os.system('pause')
if __name__ == "__main__":
main()
pyi-makespec -F demo.py
.spec 文件。pyinstaller demo.spec
Spec 文件主要包含四个类:
datas:用于添加额外数据文件,格式为 [('源路径', '目标相对路径')]。binaries:添加二进制文件(如 DLL)。hiddenimports:手动指定未自动检测到的导入模块。-F 模式下通常没有此部分。# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['demo.py'],
pathex=[],
binaries=[],
datas=[('core\dict.txt', 'core')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
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='demo',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
注意:在 JSON 字符串中,反斜杠需转义,上述代码中的 core\dict.txt 在 JSON 中应写作 core\\dict.txt。
如果程序有 Bug,打包后的 exe 可能直接闪退而不显示错误信息。建议在代码中添加异常捕获,或在打包时使用 console=True 查看控制台报错。
用于打包的 Python 解释器路径不能包含中文或空格。如果必须使用,可修改 Python 安装目录下的 scripts/pyinstaller-script.py 文件中的 python.exe 路径,或创建一个新的无特殊字符的安装目录。
最好在 py 文件首行添加 # -*- coding:utf-8 -*-,否则 exe 容易因编码问题报错。
确保在 Spec 文件的 datas 字段中正确声明了资源文件路径,并在代码中使用 resource_path 函数获取路径。
使用 UPX 压缩可显著减小 exe 体积。在 Spec 文件中设置 upx=True(默认通常开启),并确保安装了 UPX 工具。
设置 strip=True 可去除符号表,减小体积但增加调试难度。
在 Analysis 类的 excludes 列表中排除不需要的模块,减少包体积。
PyInstaller 提供了灵活的打包方案,命令行适合快速测试,Spec 文件适合生产环境部署。通过合理配置参数和处理资源路径,可以生成稳定、易用的可执行文件。遇到打包问题时,优先检查路径编码、依赖缺失及资源引用是否正确。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online