本篇博客将简要介绍如何使用pyinstaller构建、打包一个python程序。这里我们将以C风格的方式(.spec配置文件 + build脚本)来打包我们的目标源码。因此我们需要准备如下的内容:
main.py,目标源码;build_config.spec,构建配置;build.py,构建脚本。
一、main.py
这里我们将实现一个最基本的python程序,我们期望通过如下的方式来调用它:
(base)PS C:\Users\x\Downloads\src> python main.py --print "Hello"
[INFO] 接收到的参数内容: Hello
其源代码如下:
# main.py
# 标准库
import argparse
import sys
# 第三方库
from colorama import init, Fore, Style
# 初始化 colorama
init()
def main():
# 1. 创建 ArgumentParser 对象
parser = argparse.ArgumentParser(description="一个用于演示 PyInstaller 打包的示例程序")
# 2. 添加参数 --print
parser.add_argument('--print', type=str, help='需要打印的字符串内容')
# 3. 解析参数
args = parser.parse_args()
# 4. 业务逻辑
if args.print:
# 使用第三方库 colorama 输出绿色文字
print(f"{Fore.GREEN}[INFO] 接收到的参数内容: {Style.RESET_ALL} {args.print}")
else:
print(f"{Fore.RED}[ERROR] 未提供 --print 参数。{Style.RESET_ALL}")
print(f"用法示例: {sys.argv[0]} --print \"Hello World\"")
if __name__ == "__main__":
main()
这里我们编写了一个最基本的IO程序,同时加入了第三方库colorama,让程序更贴近实际使用的情况。
二、build_config.spec
在验证了上述代码的正确性后,我们尝试使用pyinstaller对其进行打包。为了更好的控制编译过程,我们这里不直接采用pyinstaller xxxxxx的方式来编译,而是像makefile一样编写一个专门的文件。其源码如下:
# demo_app.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['main.py'], # 源代码列表
pathex=[], # 额外的搜索路径
binaries=[], # 需要包含的二进制文件 (如 .dll, .so)
datas=[], # 非代码资源文件 (如图片, 配置文件)
hiddenimports=[], # PyInstaller 无法自动检测到的隐式导入库
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_app', # 输出的可执行文件名
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True, # 是否使用 UPX 压缩
upx_exclude=[],
runtime_tmpdir=None,
console=True, # True=显示控制台(命令行程序), False=隐藏(GUI程序)
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
三、build.py
在编写完了上述配置文件后,我们可以用类似make xxxx.conf的方式来调用它;同样的,我们这里依然采用编写一个脚本(bash、powershell均可)来控制构建的流程,为了方便,我们这里依然选择使用python来作为构建脚本。其源码如下:
# build.py
import PyInstaller.__main__
import os
import shutil
def build():
print("使用 Spec 文件开始构建...")
# 1. clean原有构建文件
if os.path.exists('dist'):
shutil.rmtree('dist')
if os.path.exists('build'):
shutil.rmtree('build')
# 2. 选择配置文件 build_config.spec
params = [
'build_config.spec',
# 构建前清理文件
'--clean'
]
# 3. (Make) 调用pyinstaller执行构建
PyInstaller.__main__.run(params)
print("构建完成!")
if __name__ == "__main__":
build()
四、验证
在编写完成了上述代码之后,我们的工程目录如下:
.
├── build_config.spec
├── build.py
└── main.py
我们首先进行main.py的功能验证:
(base)PS C:\Users\x\Downloads\src> python main.py --print "功能验证"
[INFO] 接收到的参数内容: 功能验证
确认没有问题之后,通过build.py进行编译:
(base)PS C:\Users\x\Downloads\src> python build.py
使用 Spec 文件开始构建...
579 INFO: PyInstaller: 6.11.1, contrib hooks: 2025.0
580 INFO: Python: 3.12.4 (conda)
602 INFO: Platform: Windows-11-10.0.26100-SP0
602 INFO: Python environment: C:\Users\x\miniconda3
609 INFO: Removing temporary files and cleaning cache in C:\Users\x\AppData\Local\pyinstaller
611 INFO: Module search paths (PYTHONPATH):
['C:\\Users\\x\\Downloads\\src',
'C:\\Users\\x\\miniconda3\\python312.zip',
'C:\\Users\\x\\miniconda3\\DLLs',
'C:\\Users\\x\\miniconda3\\Lib',
'C:\\Users\\x\\miniconda3',
'C:\\Users\\x\\miniconda3\\Lib\\site-packages',
'C:\\Users\\x\\miniconda3\\Lib\\site-packages\\win32',
'C:\\Users\\x\\miniconda3\\Lib\\site-packages\\win32\\lib',
'C:\\Users\\x\\miniconda3\\Lib\\site-packages\\Pythonwin',
'C:\\Users\\x\\Downloads\\src']
1367 INFO: checking Analysis
1367 INFO: Building Analysis because Analysis-00.toc is non existent
1367 INFO: Running Analysis Analysis-00.toc
1367 INFO: Target bytecode optimization level: 0
1369 INFO: Initializing module dependency graph...
1370 INFO: Initializing module graph hook caches...
1398 INFO: Analyzing base_library.zip ...
3690 INFO: Processing standard module hook 'hook-encodings.py' from 'C:\\Users\\x\\miniconda3\\Lib\\site-packages\\PyInstaller\\hooks'
5436 INFO: Processing standard module hook 'hook-pickle.py' from 'C:\\Users\\x\\miniconda3\\Lib\\site-packages\\PyInstaller\\hooks'
6307 INFO: Processing standard module hook 'hook-heapq.py' from 'C:\\Users\\x\\miniconda3\\Lib\\site-packages\\PyInstaller\\hooks'
6755 INFO: Caching module dependency graph...
6865 INFO: Looking for Python shared library...
6872 INFO: Using Python shared library: C:\Users\x\miniconda3\python312.dll
6872 INFO: Analyzing C:\Users\x\Downloads\src\main.py
6934 INFO: Processing module hooks (post-graph stage)...
6938 INFO: Performing binary vs. data reclassification (2 entries)
6941 INFO: Looking for ctypes DLLs
6947 INFO: Analyzing run-time hooks ...
6949 INFO: Including run-time hook 'pyi_rth_inspect.py' from 'C:\\Users\\x\\miniconda3\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks'
6953 INFO: Looking for dynamic libraries
7150 INFO: Extra DLL search directories (AddDllDirectory): []
7151 INFO: Extra DLL search directories (PATH): []
7702 INFO: Warnings written to C:\Users\x\Downloads\src\build\build_config\warn-build_config.txt
7725 INFO: Graph cross-reference written to C:\Users\x\Downloads\src\build\build_config\xref-build_config.html
7762 INFO: checking PYZ
7762 INFO: Building PYZ because PYZ-00.toc is non existent
7762 INFO: Building PYZ (ZlibArchive) C:\Users\x\Downloads\src\build\build_config\PYZ-00.pyz
8015 INFO: Building PYZ (ZlibArchive) C:\Users\x\Downloads\src\build\build_config\PYZ-00.pyz completed successfully.
8029 INFO: checking PKG
8029 INFO: Building PKG because PKG-00.toc is non existent
8029 INFO: Building PKG (CArchive) demo_app.pkg
9912 INFO: Building PKG (CArchive) demo_app.pkg completed successfully.
9914 INFO: Bootloader C:\Users\x\miniconda3\Lib\site-packages\PyInstaller\bootloader\Windows-64bit-intel\run.exe
9914 INFO: checking EXE
9915 INFO: Building EXE because EXE-00.toc is non existent
9915 INFO: Building EXE from EXE-00.toc
9915 INFO: Copying bootloader EXE to C:\Users\x\Downloads\src\dist\demo_app.exe
9925 INFO: Copying icon to EXE
9933 INFO: Copying 0 resources to EXE
9934 INFO: Embedding manifest in EXE
9941 INFO: Appending PKG archive to EXE
9957 INFO: Fixing EXE headers
10044 INFO: Building EXE from EXE-00.toc completed successfully.
构建完成!
(base)PS C:\Users\x\Downloads\src>
我们可以看到,已经成功编译了main.py,输出的结果为dist/demo_app.exe,我们尝试调用它:
(base)PS C:\Users\x\Downloads\src> .\dist\demo_app.exe --print "验证构建产物"
[INFO] 接收到的参数内容: 验证构建产物
至此我们这里完成了通过pyinstaller进行python程序打包的这一目的。


