在创建了独立应用(自包含该应用的依赖包)之后,还可以使用 PyInstaller 将 Python程序生成可直接运行的程序,这个程序就可以被分发到对应的 Windows、Linux或 Mac OS 平台上运行。
Python 默认并不包含 PyInstaller 模块,因此需要自行安装 PyInstaller 模块。
pip install pyinstaller
注意:建议使用 pip 在线安装的方式来安装 PyInstaller 模块,不要使用离线包的方式来安装,因为 PyInstaller 模块还依赖其他模块,pip 在安装 PyInstaller 模块时会先安装它的依赖模块。
pyinstaller -F main.py #根据py文件生成
pyinstaller xxx.spec #根据spec文件生成
选项 | 介绍 |
---|---|
-F , –onefile |
打包一个单个可执行文件 |
-D , –onedir |
打包多个文件,在dist中生成很多依赖文件,适合以框架形式编写工具代码,我个人比较推荐这样,代码易于维护(默认) |
-K , –tk |
在部署时包含 TCL/TK |
-a , –ascii |
不包含编码.在支持Unicode的python版本上默认包含所有的编码. |
-d , –debug |
产生debug版本的可执行文件 |
-w ,–windowed ,–noconsole |
使用Windows子系统执行.当程序启动的时候不会打开命令行(只对Windows、mac有效) |
-c ,–nowindowed ,–console |
使用控制台子系统执行(只对Windows、mac有效)pyinstaller -c xxxx.pypyinstaller xxxx.py –console(默认) |
-s ,–strip |
可执行文件和共享库将run through strip.注意Cygwin的strip往往使普通的win32 Dll无法使用. |
-X , –upx |
如果有UPX安装(执行Configure.py时检测),会压缩执行文件(Windows系统中的DLL也会)(参见note) |
-o DIR , –out=DIR |
指定spec文件的生成目录,如果没有指定,而且当前目录是PyInstaller的根目录,会自动创建一个用于输出(spec和生成的可执行文件)的目录.如果没有指定,而当前目录不是PyInstaller的根目录,则会输出到当前的目录下. |
-p DIR , –path=DIR |
设置导入路径(和使用PYTHONPATH效果相似).可以用路径分割符(Windows使用分号,Linux使用冒号)分割,指定多个目录.也可以使用多个-p参数来设置多个导入路径,让pyinstaller自己去找程序需要的资源 |
–icon=<FILE.ICO> ,–i=<FILE.ICO> |
将file.ico添加为可执行文件的资源(只对Windows系统有效),改变程序的图标 pyinstaller -i ico路径 xxxxx.py |
–icon=<FILE.EXE,N> ,–icon=<FILE.EXE,N> |
将file.exe的第n个图标添加为可执行文件的资源(只对Windows系统有效) |
-v FILE , –version=FILE |
将verfile作为可执行文件的版本资源(只对Windows系统有效) |
-n NAME , –name=NAME |
可选的项目(产生的spec的)名字.如果省略,第一个脚本的主文件名将作为spec的名字 |
我们用main.spec文件记录打包需要的文件依赖等,pyinstaller参数的本质可认为是 .spec文件中的配置属性。main.spec文件可按照类型直接拷贝模板即可,之后进行修改。
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
'''
以py文件为输入,分析py文件的以来模块,并生成相应信息
'''
a = Analysis(['main.py', #要打包的py文件列表,与main.py同级的可以不写
'./cfg/__init__.py',
'./cfg/setting.py',
'./comm/__init__.py',
'./comm/logger.py',
'./comm/utils.py',
'./handler/__init__.py',
'./handler/invite_handler.py',
'./handler/sip_parse_handler.py',
'./handler/subscribe_handler.py',
'./my_thread/__init__.py',
'./my_thread/alarm.py',
'./my_thread/audio_media.py',
'./my_thread/audio_media_rtp.py',
'./my_thread/broadcast.py',
'./my_thread/my_sip_epoll.py',
'./my_thread/timer.py',
'./my_thread/video_media.py',
'./redis_utils/__init__.py',
'./redis_utils/redis_keys.py',
'./redis_utils/redis_work.py',
'./__init__.py',
'./device.py',
'./std/ietf/__init__.py',
'./std/ietf/rfc1035.py',
'./std/ietf/rfc2198.py',
'./std/ietf/rfc2396.py',
'./std/ietf/rfc2617.py',
'./std/ietf/rfc2833.py',
'./std/ietf/rfc3261.py',
'./std/ietf/rfc3489.py',
'./std/ietf/rfc5658.py',
'./std/ietf/rfc6455.py',
'./std/ietf/rfc7064.py',
'./std/ietf/rfc7065.py',
'./std/itu_t/__init__.py',
'./std/w3c/__init__.py',
'./std/w3c/simplexml.py',
'./std/__init__.py'],
pathex=['./'], #项目目录
binaries=[], #程序调用外部pyd、dll等二进制文件路径,以元组传入
datas=[], #程序的资源路径,以元组传入
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[], #去掉不需要的引入model
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
#.pyz压缩包,包含程序运行依赖
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
#生成exe的属性和配置
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True )