PyInstaller 是一个非常强大的工具,用于将 Python 脚本打包成独立的可执行文件(如 .exe
文件),使得 Python 应用程序可以在没有安装 Python 环境的机器上运行。
PyInstaller 的核心目标是将 Python 脚本及其依赖的模块打包成一个独立的可执行文件。它的工作原理可以分为以下几个步骤:
(1)分析脚本依赖
PyInstaller 会分析你的 Python 脚本,找出所有导入的模块(包括标准库模块和第三方库模块)。它会递归地解析这些模块的依赖关系,确保所有必要的文件都被包含在打包结果中。
(2)打包资源
除了代码文件,PyInstaller 还可以将其他资源(如配置文件、图片、数据文件等)打包到最终的可执行文件中。这些资源可以指定路径,以便在运行时正确加载。
(3)生成可执行文件
PyInstaller 支持两种打包模式:
单文件模式(--onefile
):将所有内容打包到一个 .exe
文件中。运行时,程序会自动解压到临时文件夹中,运行完成后删除临时文件。
文件夹模式(默认):将所有内容打包到一个文件夹中,生成一个 .exe
文件和一个包含依赖的文件夹。这种方式运行速度更快,但分发时需要整个文件夹。
可以通过 pip 安装:
pip install pyinstaller
pyinstaller main.py
运行该命令后,PyInstaller 会在当前目录下生成一个 dist
文件夹,其中包含打包后的 .exe
文件。
为了更好地控制打包过程,可以使用一些常用选项:
pyinstaller -F main.py
pyinstaller -w main.py
pyinstaller -F -i icon.ico main.py
pyinstaller --hidden-import some_module main.py
pyinstaller --add-data "data_folder;data_folder" main.py
pyinstaller --workpath build --distpath output script.py
打包完成后,PyInstaller 会在当前目录下生成以下文件夹和文件:
dist
:包含打包后的 .exe
文件(或单文件 .exe
)。
build
:包含打包过程中生成的临时文件。
main.spec
:打包配置文件,用于后续的定制化打包。
依赖问题:如果项目中使用了特殊的库(如 PyQt、Pandas 等),可能需要额外配置或指定隐藏导入。
文件路径问题:在打包时,相对路径可能会失效,建议在代码中使用绝对路径。
单文件模式(-F)的限制:单文件模式下,程序运行时会临时解压到临时目录,可能会导致路径问题或性能问题。
测试:打包完成后,务必在不同的环境中测试 .exe
文件,确保其正常运行。
PyInstaller 会为每个脚本生成一个 .spec
文件,用于描述打包过程。可以编辑这个文件,以实现更复杂的打包需求。
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['script.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='script',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='script',
)
添加隐藏导入:
a = Analysis(
...
hiddenimports=['some_module'],
)
a = Analysis(
...
datas=[('data_folder', 'data_folder')],
)
指定打包模式:
单文件模式:
exe = EXE(
...
one_file_mode=True,
)
文件夹模式:
exe = EXE(
...
one_file_mode=False,
)
.spec
文件打包pyinstaller script.spec