pyinstaller是python的打包工具,结合我的工程,记录下我的使用过程及经验总结。
1.pyinstaller的简单使用
1.1 打包成一个文件
先cd切换到工程目录下,再执行:
pyinstaller -i study.icns -n exam -w -F main.py
参数说明:
-i: 指定app的图标;
-n: 指定app的名字,默认是主入口的py文件,比如main.py;
-w: 程序运行时不弹出控制台窗口
-F: 生成单个文件(小工程,文件少使用这个即可)
上面语句执行完后,便会在工程根目录上生成:
exam.spec文件,build和dist文件夹。app便在dist文件夹中。
1.2 打包成一个文件夹
-D可以去掉,默认情况下就是打包成文件夹
pyinstaller -w -D main.py
参数说明:
-D: 生成文件夹(大工程,文件多建议使用)
1.3 二次打包
有了spec文件(我的理解是spec文件已记录了打包所需要的相关信息),就不用使用1.1的方法了,可以直接这样:
pyinstaller -y exam.spec
参数说明:
-y: 替换输出目录(默认值:SPECPATH / dist / SPECNAME)而不要求确认.
删除打包生成的文件:
rm -rf build dist
1.4 spec文件
使用前面的方面已经得到了spec文件,当前也可以使用下面方法得到:
pyinstaller options..script.py
正常使用中我们是不需要修改spec文件的,但是下面几种情况需要修改spec文件:
1.需要打包资源文件
2.需要include一些PyInstaller不知道的run-time库
3.为可执行文件添加run-time 选项
4.多程序打包
可以通过下面命令生成spec文件
pyi-makespec options script.py [other scripts ...]
修改完spec文件,就可以通过下面命令来生成app文件了
pyinstaller options script.spec
1.5 spec文件解析
下面是spec文件(我工程的)
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['/Users/wenlong/exam_demo'],
binaries=[],
datas=[],
hiddenimports=[],
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='exam',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False , icon='study.icns')
app = BUNDLE(exe,
name='exam.app',
icon='study.icns',
bundle_identifier=None)
spec文件中主要包含4个class: Analysis, PYZ, EXE和COLLECT。
Analysis以py文件为输入,它会分析py文件的依赖模块,并生成相应的信息。
PYZ是一个.pyz的压缩包,包含程序运行需要的所有依赖。
EXE根据上面两项生成。
COLLECT生成其他部分的输出文件夹,COLLECT也可以没有。
如果要添加资源进去,那么可以修改:
datas=[('res/bg.jpg', 'res'), ('exam.db', '.')]
列表里面是元组,左边是你要添加的filename(相对路径即可),右边是拷贝到项目中之后的文件夹名字。
比如:
- (‘res/bg.jpg’, ‘res’) 中的 ‘res/bg.jpg’ 表示工程根目录下res文件夹下有bg.jpg图片,拷贝到项目之后的res文件夹。
- (‘exam.db’, ‘.’) 中的’exam.db’是工程根目录下的文件,’.'表示根目录,即拷贝到项目中的根目录下。
2. 打包图片等资源
光修改了spec文件还是不行的,还需要在python中将获取图片/资源的的路径方法改一下,如下:
# 获取路径
import os, sys
def getPath(filename):
# 方法一(如果要将资源文件打包到app中,使用此法)
bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
path = os.path.join(bundle_dir, filename)
# 方法二获取路径可以,但如果打包资源好像不行。
# path = os.path.join(os.path.dirname(sys.argv[0]), filename)
return path
使用上面的方法获取路径,再利用–add-data命令或者修改使用.spec文件再打包即可。
2020-03-02