PyInstaller是一个程序,它将Python程序冻结(包)为独立的可执行文件,在Windows,GNU/Linux,Mac OS X,FreeBSD,OpenBSD,Solaris和AIX下。与类似工具相比,它的主要优点是PyInstaller与Python 3.6-3.9配合使用,由于透明压缩,它构建了较小的可执行文件,它是完全多平台的,并使用操作系统支持来加载动态库,从而确保完全兼容。
可以传递一个或多个 Python 脚本的文件名,也可以传递一个 .spec 文件名。
在第一种情况下,将生成一个.spec
文件(就像这样)并立即处理它。pyinstaller pyi-makespec
pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME]
[--add-data ]
[--add-binary ] [-p DIR]
[--hidden-import MODULENAME]
[--collect-submodules MODULENAME]
[--collect-data MODULENAME] [--collect-binaries MODULENAME]
[--collect-all MODULENAME] [--copy-metadata PACKAGENAME]
[--recursive-copy-metadata PACKAGENAME]
[--additional-hooks-dir HOOKSPATH]
[--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES]
[--key KEY] [--splash IMAGE_FILE]
[-d {all,imports,bootloader,noarchive}]
[--python-option PYTHON_OPTION] [-s] [--noupx]
[--upx-exclude FILE] [-c] [-w]
[-i ]
[--disable-windowed-traceback] [--version-file FILE]
[-m ] [--no-embed-manifest] [-r RESOURCE]
[--uac-admin] [--uac-uiaccess] [--win-private-assemblies]
[--win-no-prefer-redirects]
[--osx-bundle-identifier BUNDLE_IDENTIFIER]
[--target-architecture ARCH] [--codesign-identity IDENTITY]
[--osx-entitlements-file FILENAME] [--runtime-tmpdir PATH]
[--bootloader-ignore-signals] [--distpath DIR]
[--workpath WORKPATH] [-y] [--upx-dir UPX_DIR] [-a]
[--clean] [--log-level LEVEL]
scriptname [scriptname ...]
参数 | 解释 |
---|---|
-h, --help | 显示此帮助消息并退出 |
-v, --version | 显示程序版本信息并退出。 |
–distpath DIR | 将捆绑的应用放在何处(默认:./dist) |
–workpath WORKPATH | 放置所有临时工作文件的位置,.log、.pyz 等(默认:./build) |
-y, --noconfirm | 替换输出目录(默认:SPECPATH/dist/SPECNAME),而不要求确认 |
–upx-dir UPX_DIR | UPX 实用程序的路径(默认:搜索执行路径) |
-a, --ascii | 不包括 Unicode 编码支持(默认:如果可用,则包括) |
–clean | 在构建之前清理 PyInstaller 缓存并删除临时文件。 |
–log-level LEVEL | 构建时控制台消息中的详细信息量。级别可以是 TRACE、DEBUG、INFO、WARN、ERROR、CRITICAL(默认值:INFO)之一。 |
–uac-admin | 添加管理员权限通过命令行的方式,例如pyinstaller -D -c --uac-admin main.py |
参数 | 解释 |
---|---|
-D, --onedir | 创建包含可执行文件的单文件夹捆绑包(默认) |
-F, --onefile | 创建单文件捆绑的可执行文件。 |
–specpath DIR | 用于存储生成的 spec 文件的文件夹(默认:当前目录) |
-n NAME, --name NAME | 要分配给捆绑的应用程序和规范文件的名称(默认:第一个脚本的基本名称) |
参数 | 解释 |
---|---|
–add-data |
要添加到可执行文件的其他非二进制文件或文件夹。路径分隔符是特定于平台的,(在Windows和大多数unix系统上)被使用。此选项可以多次使用。分隔符可选= 、; 、: 或者空格 |
–add-binary |
要添加到可执行文件的其他二进制文件。有关更多详细信息,请参阅该选项。此选项可以多次使用。--add-data |
-p DIR, --paths DIR | 用于搜索导入的路径(如使用 PYTHONPATH)。允许使用多个路径、以 分隔或多次使用此选项。等效于在规范文件中提供参数。':'``pathex |
–hidden-import MODULENAME, --hiddenimport MODULENAME | 命名在脚本代码中不可见的导入。此选项可以多次使用。 |
–collect-submodules MODULENAME | 从指定的包或模块中收集所有子模块。此选项可以多次使用。 |
–collect-data MODULENAME, --collect-datas MODULENAME | 从指定的包或模块收集所有数据。此选项可以多次使用。 |
–collect-binaries MODULENAME | 从指定的包或模块收集所有二进制文件。此选项可以多次使用。 |
–collect-all MODULENAME | 从指定的包或模块中收集所有子模块、数据文件和二进制文件。此选项可以多次使用。 |
–copy-metadata PACKAGENAME | 复制指定包的元数据。此选项可以多次使用。 |
–recursive-copy-metadata PACKAGENAME | 复制指定包及其所有依赖项的元数据。此选项可以多次使用。 |
–additional-hooks-dir HOOKSPATH | 用于搜索挂钩的其他路径。此选项可以多次使用。 |
–runtime-hook RUNTIME_HOOKS | 自定义运行时挂钩文件的路径。运行时挂钩是与可执行文件捆绑在一起的代码,在任何其他代码或模块之前执行,以设置运行时环境的特殊功能。此选项可以多次使用。 |
–exclude-module EXCLUDES | 将忽略的可选模块或包(Python 名称,而不是路径名)(好像找不到它)。此选项可以多次使用。 |
–key KEY | 用于加密 Python 字节码的密钥。需要安装pycrypto可以用p代替ycryptodome代替 |
–splash IMAGE_FILE | (实验性)将带有图像IMAGE_FILE的初始屏幕添加到应用程序中。初始屏幕可以在解压缩时显示进度更新。 |
参数 | 解释 |
---|---|
-c, --console, --nowindowed | 打开标准 I/O 的控制台窗口(默认)。在 Windows 上,如果第一个脚本是".pyw"文件,则此选项不起作用。 |
-w, --windowed, --noconsole | Windows 和 Mac OS X:不为标准 I/O 提供控制台窗口。在 Mac OS 上,这也会触发构建 Mac OS .app捆绑包。在 Windows 上,如果第一个脚本是".pyw"文件,则会自动设置此选项。此选项在 *NIX 系统上被忽略。 |
-i --icon |
文件.ico:将图标应用于 Windows 可执行文件。文件.exe,ID:从exe中提取带有ID的图标。FILE.icns:将图标应用于 Mac OS 上的.app捆绑包。使用"NONE"不应用任何图标,从而使操作系统显示一些默认值(默认:应用 PyInstaller 的图标) |
–disable-windowed-traceback | 在窗口(无控制台)模式下禁用未处理异常的回溯转储(仅限 Windows 和 macOS),而是显示一条消息,指出此功能已禁用。 |
参数 | 解释 |
---|---|
–version-file FILE | 将版本资源从 FILE 添加到 exe。 |
-m –manifest |
将清单文件或 XML 添加到 exe。 |
–no-embed-manifest | 生成外部.exe.manifest 文件,而不是将清单嵌入到 exe 中。仅适用于一进制模式;在单文件模式下,无论此选项如何,清单始终是嵌入的。 |
-r RESOURCE, --resource RESOURCE | 将资源添加或更新到 Windows 可执行文件。资源是一到四个项目,FILE[,TYPE[,NAME[,LANGUAGE]]]。文件可以是数据文件或 exe/dll。对于数据文件,至少必须指定 TYPE 和 NAME。LANGUAGE 默认为 0 或指定为通配符 * 以更新给定 TYPE 和 NAME 的所有资源。对于 exe/dll 文件,如果省略了 TYPE、NAME 和 LANGUAGE 或指定为通配符 *,则 FILE 中的所有资源都将添加/更新到最终的可执行文件中。此选项可以多次使用。 |
–uac-admin | 使用此选项将创建一个清单,该清单将在应用程序启动时请求提升。 |
–uac-uiaccess | 使用此选项允许提升的应用程序使用远程桌面。 |
pyinstaller -F main.py
执行pyinstaller 提供的调试打包命令,查看打包错误日志,通过日志排查问题原因
-D 参数表示打调试包,将展示生成的各种依赖文件,等待打包结束,查看 build/main/warn-main.txt 日志警告文件
pyinstaller -D main.py
添加用户依赖包
分析日志发现缺失模块,现在通过命令行,把用户第三方依赖模块搜索路径添(请使用自己电脑定义的安装目录)加进打包命令,
下面提供示例,site-packages可以不用添加的,即如果你没有使用pip -target 安装第三方模块到自己指定的目录,这一步可以省略。有些IDE工具会创建自己的安装包路径,所以请添加IDE的安装包的路径
pyinstaller -D -p D:\\Python\\Python38\\Lib\\site-packages main.py
命令行打包多文件
pyinstaller [主文件] -p [其他文件1] -p [其他文件2]
--hidden-import [自建模块1]
--hidden-import [自建模块2]
# 以上为一整条命令
例如:pyinstaller -F start_menu.py -p check_default_speedup.py -p check_server_os.py -p check_speedup.py
通过upx可显著见小程序体积。
需要下载upx.exe
打包时加上以下参数:
--upx-dir UPX_DIR
UPX_DIR指向upx的下载目录不用具体到文件,一般建议直接和python解释器放在一起就好。pyinstaller会自动选择进行压缩(可写一个错误路径查看两次打的包大小)
spec
方式spec
文件打开终端进入项目路径下,输入指令: pyinstaller -makespec xxx.py
,或者其他命令回车,程序结束后
当前目录(默认)下生成两个文件夹(bulid、dist)和一个文件start_menu.spec,现在删除两个文件夹,只保留start_menu.spec文件。
资源文件包括打包的python项目使用的相关文件,如图标文件,文本文件等。对于此类资源文件的打包需要设置Analysis的datas,
`datas接收元组:
datas写入必须是一对2元素元组,每一个元组代表一个文件。
元素第一个是要打包文件的路径(可用相对路径),第二个是要打包进exe后的路径(只能用相对路径以为./开头,根目录下的话可省略./)
datas=[('logo/icon.ico','./logo'),('image/xxx.png', 'image')]
递归深度设置
在打包导入某些模块时,常会出现"RecursionError: maximum recursion depth exceeded"的错误,这可能是打包时出现了大量的递归超出了python预设的递归深度。因此需要在spec文件上添加递归深度的设置,设置一个足够大的值来保证打包的进行,
import sys
sys.setrecursionlimit(5000)
去除不必要的模块import
有时需要让pyinstaller不打包某些用不到的模块,可通过在excludes=[]中添加此模块实现,如
excludes=['zmq']
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['start_menu.py','check_default_speedup.py', 'check_server_os.py', 'check_speedup.py'],#此项目中所有的python脚本
pathex=[ 'D:\\Project\\python\\xxxTool'], # 项目绝对路径,此处很重要。
binaries=[],
datas=[],#此列表存放所有的资源文件,每个文件是一个二元组元素,例如[('image/xxx.png', '.')] 把image/xxx.png下打包到根目录下(一般建议前后目录一致,这里用.只是演示),可以用同样方法添加多个图片元素等。
#add_files = [ ('fonts\\font.ttf', 'fonts'),
#('images\\*.png', 'images'),
#('images\\flappy.ico', 'images'),
#('audios\\*.wav', 'audios'),]
hiddenimports=[], # 同命令行--hidden-import [自建模块1]参数可多次添加,身份证项目中就在此处添加了两个工具模块py文件
hookspath=[],
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='start_menu', #打包程序的名字
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True, # 此处console=True表示,打包后cmd窗口运行,不影响原程序运行
icon='xxxxx.ico', # 修改图标,可不带此参数同命令行-i xxx.ico
uac_admin=True # 以管理员方式运行
默认情况下,pyinstaller
只打包 *.py 文件,对于其它文件,如图片、文本文件等,需要添加额外的参数手动指定加入打包行列,或者更改特定的 spec 文件。
要将文件添加到捆绑包,请创建一个描述文件的列表,并将其提供给调用。
使用 --add-data
命令选项或将它们作为列表添加到 spec 文件中,从而将数据文件添加到捆绑包中。
使用 spec 文件时,请提供一个列表,将文件描述为 参数的值。数据文件列表是元组列表。每个元组都有两个值,这两个值都必须是字符串:datas=Analysis
用法的注意事项有几个:
写–add-data有时候加上引号会报错,这是因为在win环境和linux下不一样具体使用哪个请尝试吧。
--add-data
后面可以加=,也可以直接空格,效果一样。--add-data
后面的参数值里,有两部分,用 ;
隔开(windows用分号号,部分其他系统用:
隔开),前面是指打包前文件所在的位置,后面是指打包后你希望文件所在的位置--add-data image1.png;img
的意思是把当前目录里一个叫 “image1.png” 的文件打包进去,但是放在打包后的 img
目录下,也就是变成 img/image1.png
,文件名不变。--add-data
可以用多次,可以一个文件一个文件地加,也可以整个文件夹一起加--add-data 'images;images'
也就是把当前目录下 images 文件夹里的文件都打包进去,打包后的目录也是 images 一样的文件夹下。例如,要将单个自述文件添加到单文件夹应用程序的顶层,可以按如下方式修改规范文件:
pyinstaller -F --add-data 'use_ico.png;./' format_conversion.py
说明中–add-data后的文件和保存目录说是可以用分好和冒号但是实际使用冒号发现报错。
命令行:
pyinstaller --add-data 'src/README.txt;.' myscript.py
spec 文件:
a = Analysis(...
datas=[ ('src/README.txt', '.') ],
...
)
字符串可以使用或作为路径分隔符。可以使用"glob"缩写指定输入文件。例如,要包含某个文件夹中的所有文件:/mygame/ data
文件夹中的所有mp3文件都将复制到捆绑应用程序中。/mygame/sfx/*.mp3 sfx
added_files = [
( '/mygame/data', 'data' ),
( '/mygame/sfx/*.mp3', 'sfx' )
]
指定让 图片文件 也可以打包进去,当前目录下,有两个图片文件:
images/alien.bmp
images/ship.bmp
pyinstaller的官方提供了两种方式用来加入额外的文件:
二进制文件是指 DLL、动态库、共享对象文件等,PyInstaller 将搜索进一步的二进制依赖项。图像和 PDF 等文件应进入 .datas
使用 --add-binary
命令选项或将它们作为列表添加到 spec 文件中,从而将二进制文件添加到捆绑包中。
在 spec 文件中,创建描述所需文件的元组列表。将元组列表分配给 Analysis 的参数。binaries=
添加二进制文件的工作方式与添加数据文件类似。如添加二进制文件中所述,每个元组应具有两个值:
PyInstaller通过分析导入的模块来了解和库。有时不清楚是否导入了模块;在这种情况下,请使用 --hidden-import
命令选项。但即便如此,也可能无法找到所有依赖项
用法同添加文件
使用单文件打包出来的exe会先解压再运行,所以打包出来的exe在运行时,它的工作路径和它解压到的路径
程序一般首先都是在工作路径查找你所指定的文件的。直接这样执行已打包的外部文件时,程序会报找不到文件
import os
import sys
def base_path(path):
if getattr(sys, 'frozen', None):
basedir = sys._MEIPASS
else:
basedir = os.path.dirname(__file__)
return os.path.join(basedir, path)
tmd = base_path('') # 这是解压路径
cwd = os.getcwd() # 这是程序的所在路径
# 当需要调用打包的外部文件时
os.chdir(tmd) # 先把工作路径变成解压路径
# ######do() # 执行你要干的事情
# 当需要写出文件到程序所在目录时
os.chdir(cwd) # 把工作路径切换回来
# #####do() # 执行你要干的事情
或者,在程序中所有引用图片的路径,使用此函数处理
import sys
from os.path import join, abspath
def get_resource_path(relative_path):
"""
根据传入相对路径获取资源路径
在需要用到非py文件时用get_resource_path(path)替换原本直接使用相对路径方式即可
此方法适用于,在进行pyinstaller打包加了-F参数情况,否则建议不使用此方法获得更小的包
"""
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
return join(sys._MEIPASS, relative_path)
return join(abspath(""), relative_path)
PyInstaller 使用(目录)类管理文件列表。它提供了该类作为从文件夹路径生成 的便捷方法。
类的对象用作在 spec 文件中创建的类的输入。例如,分析对象的成员是包含脚本列表的目录。成员是具有模块列表的目录,依此类推。
基本上,对象包含表单的元组列表TOC
目录的行为类似于列表,并支持相同的方法,如追加、索引等。目录的行为也像一个集合,并支持采用差异和交叉点。在所有这些操作中,元组列表可以用作一个参数。
以下表达式是将文件添加到成员的等效方法:a.datas
a.datas.append( [ ('README', 'src/README.txt', 'DATA' ) ] )
a.datas += [ ('README', 'src/README.txt', 'DATA' ) ]
Tree 类是一种创建目录的方法,该目录描述目录中的部分或全部文件:
Tree(根运行时文件夹string_list代码|, prefix=, excludes=, typecode='DATA' )
None
*.ext
,这会导致排除具有此扩展名的文件DATA
extras_toc = Tree('../src/extras', prefix='extras', excludes=['tmp','*.pyc'])
将创建一个 TOC 对象,该对象列出相对路径中的所有文件,省略具有基名(或位于名为 的文件夹中)或具有 类型的文件。此目录中的每个元组都有:extras_toc``../src/extras``tmp``.pyc
extras/*filename*
../src/extras
DATA
一些二进制模块的目录的示例:
cython_mods = Tree( '..src/cy_mods', excludes=['*.pyx','*.py','*.pyc'], typecode='EXTENSION' )
# 在需要打包文件目录下新建一个test_env文件夹并cmd进入,用于创建虚拟环境
cd test_dir
python -m venv env_dir
# 成功创建虚拟环境,cmd进入test_env
cd env_dir\Scripts
# 激活虚拟环境
./env_dir/Scripts/activate
# 安装需要的包,pyinstaller必须安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ pyinstaller
# 切换到需要打包目录,进行打包
pyinstaller -F -w -i dog.ico CrazyClick.py
# 打包完成直接关闭或者exit退出该环境
exit