文章目录
PyInstaller
1. 什么是PyInstaller?
PyInstaller 是一个 Python 工具,可以将 Python 脚本打包成独立的可执行文件(如 exe
文件,适用于 Windows 系统)。它可以将 Python 脚本及其依赖项打包在一个文件或目录中,方便在没有 Python 环境的机器上运行。
2. 安装和简单的使用方式
-
安装 PyInstaller:
使用pip
安装 PyInstaller:pip install pyinstaller
-
简单使用方式:
在终端中运行以下命令,将 Python 脚本(例如my_script.py
)打包成可执行文件:pyinstaller my_script.py
默认情况下,PyInstaller 会在当前目录下生成一个
dist
文件夹,其中包含打包好的可执行文件和必要的依赖项文件。如果想生成一个单个的可执行文件(不打包成目录),可以使用以下命令:
pyinstaller --onefile my_script.py
如果不希望生成控制台窗口(例如在打包 GUI 应用程序时),可以使用:
pyinstaller --noconsole my_script.py
如果需要指定图标文件(例如
app_icon.ico
),可以使用:pyinstaller --icon=app_icon.ico my_script.py
3. spec 文件
3.1 是什么?怎么生成?
- spec 文件是 PyInstaller 的配置文件。它是一个纯文本文件,包含 PyInstaller 打包过程中的各种配置和参数。
- PyInstaller 会自动根据主脚本生成一个默认的
.spec
文件。例如,当你运行pyinstaller my_script.py
时,它会在当前目录下生成一个my_script.spec
文件。 - 你可以手动编辑这个
.spec
文件,来调整 PyInstaller 的打包行为,通常情况下,除了第一次打包以外,后续打包同一个项目都是使用.spec文件进行打包。
3.2 怎么用?
编辑 .spec
文件后,可以直接使用该文件进行打包,命令如下:
pyinstaller my_script.spec
3.3 pathex 参数详解
-
pathex 参数用于指定模块搜索路径。默认情况下,它包含程序入口文件所在目录和 PyInstaller 打包目录。
-
如果你的项目结构如下:
/my_projects /my_script my_script.py /my_module __init__.py module_a.py
那么你可以使用
pathex
参数明确指定模块搜索路径:a = Analysis( ['my_script.py'], pathex=['/my_projects/my_script', '/path/to/other/lib'], # 其他参数... )
-
如果你有自建的包(例如
my_module
),建议包含__init__.py
文件,以便 PyInstaller 可以在默认的模块搜索路径下识别该包。
-
3.4 hiddenimport 参数详解
- hiddenimport 参数用于指定隐藏的依赖模块。PyInstaller 无法自动检测某些动态导入的模块或从
.pyd
文件中导入的模块,hiddenimport
可以手动指定这些模块。
例如,如果你的程序中动态导入了a = Analysis( # 其他参数... hiddenimports=['my_module.submodule', 'some_package'], )
PIL.ImageDraw
,PyInstaller 可能会遗漏这个模块,可以通过以下方式添加:a = Analysis( # 其他参数... hiddenimports=['PIL.ImageDraw'], )
3.5 datas 参数详解
-
datas 参数用于将静态资源文件(例如 HTML、CSS、js、图片文件)打包到最终的可执行文件中。
a = Analysis( # 其他参数... datas=[ ('app/templates/', 'templates'), ('app/static/style.css', 'static'), ], )
例如,如果你的项目有一个
templates
文件夹和一个static
文件夹:my_script.py app/ templates/ index.html static/ style.css
在
.spec
文件中配置datas
参数:a = Analysis( # 其他参数... datas=[ ('app/templates', 'templates'), # 源路径是 app/templates,目标路径是 templates ('app/static/style.css', 'static'), # 源路径是 app/static/style.css,目标路径是 static ], )
打包后,这些文件将被包含在打包目录中。如果打包成单个文件(使用
--onefile
),这些资源文件会在程序运行时被解压到系统临时目录下。
3.6 console 和 uac_admin 参数
-
console 参数:用于控制是否在运行可执行文件时显示控制台窗口。例如:
pyinstaller --noconsole my_script.py
或者在
.spec
文件中设置:exe = EXE( a.scripts, a.binaries, a.zipfiles, a.datas, console=False, # 设置为 False,不显示控制台 )
-
uac_admin 参数:用于指定可执行文件需要管理员权限运行。例如:
pyinstaller --uac-admin my_script.py
或者在
.spec
文件中添加:exe = EXE( a.scripts, a.binaries, a.zipfiles, a.datas, uac_admin=True, # 需要管理员权限 )
-
总结:
- 第三方模块缺少对应组件,使用hiddenimport 参数解决问题
- 缺少的是自己的项目组件,使用pathex 参数解决问题
- 缺少的是项目的静态文件,使用datas 参数解决问题
4. 打包好的exe文件运行时的工作目录和程序入口文件的目录区别
4.1 打包成单个文件时
-
程序工作目录:可执行文件所在的目录。例如,如果可执行文件
my_script.exe
在C:\Program Files\MyApp
目录下运行,工作目录就是C:\Program Files\MyApp
。 -
程序入口文件的目录:在打包成单个文件时,程序的实际入口文件(例如
my_script.py
)被包含在可执行文件内部。运行时,程序会将这些文件解压到系统临时目录下。例如,系统临时目录可能是C:\Users\Username\AppData\Local\Temp\_MEI123456
,程序会在该目录下运行。
4.2 打包成单个目录时
-
程序工作目录:默认情况下,是可执行文件所在的目录。例如,如果可执行文件
my_script.exe
在D:\MyApp\
目录下运行,工作目录就是D:\MyApp\
。 -
程序入口文件的目录:程序入口文件(例如
my_script.py
)所在的目录是打包目录本身。例如,打包目录是dist\my_script
,其中包含可执行文件和所有依赖项,入口文件的目录是dist\my_script\
。
总结一下,无论打包方式如何,程序的工作目录通常是可执行文件所在的目录。而在打包成单个文件时,程序的实际入口文件会被隐藏在可执行文件内部,并在运行时解压到临时目录下,。