终于入门了python打包这个大话题,将目前学到的技能分享一下。
和很多博客说的一样,打包那么大是因为打包了多余的库,因此想要缩小就需要一个干净的,没有多余的库的环境进行打包。也就是虚拟环境。
想要在 pycharm 启动虚拟环境,先要安装一个 pipenv。按下 win+r 后输入 cmd 打开命令面板,输入 pip install pipenv
即可安装。
安装后,我们需要得到名为 “pipenv.exe” 文件的路径,也就是 pipenv 虚拟环境的安装路径。查看的方法有很多,或许是能力原因本人试过的都不怎么好使,还是最朴素的方法最稳定:
是的,直接点开此电脑在右上角搜索文件即可(慢是慢了点但是亲测有效)!
然后我们打开 pycharm 选择新建项目
点击三角形符号, pycharm 就会为这个项目创建一个干净的虚拟环境。
然后选择好虚拟环境的类型,也就是上面安装的 pipenv。
如果pipenv可执行文件那一栏是空着的,那么就把上一步中得到的 “pipenv.exe” 的路径复制过去即可。
一切就绪,点击创建。
至此如果都成功,那么恭喜你得到了一个干净的python编程环境,在这个环境下打包是最小的。但是具体实现还有一些细节。
点击左下方栏目中的 python 软件包,那么将会显示在当前环境下安装的所有的库
可以发现非常的干净,只有三个库。但是这么点库是无法达成项目需求的,因此我们需要添加软件包到当前环境上。
这一步很重要,切记不要在本地的cmd pip install
安装第三方库后,直接在虚拟环境中使用,这样子库内还是会附带很多多余的东西,就丧失了使用虚拟环境的意义。
那么怎样在 pycharm 提供的虚拟环境下安装呢。
依旧是下方栏目,选择“终端”
然后就会出现一个类似cmd的控制台。或许这时候你就会迫不及待的在这里 pip install
各种各样的库,但是请注意,左上方这里显示了“本地”,这是本地的 cmd,并不是我们虚拟环境的。
那么怎么打开虚拟环境的 cmd 进行安装呢,操作步骤非常简单。
点击“本地”旁边的向下箭头,选择 “command prompt” ,然后就切换到了虚拟环境提供的 cmd 了。
我们最终在这个地方 pip install Pyinstaller
以及其他各种的库,然后在这里输入 Pyinstaller
命令打包即可。
这个方法打包后效果非常显著,本人一个用本地 cmd 打包 300M 的项目用了虚拟环境后只有 10M。
相信大家编写的程序都经常需要调用存在本地的各种图片啊字体什么的对吧。但是直接 Pyinstaller
却不能将这些资源一起打包进 exe 文件里。也就是说,如果打包后的程序按照程序中的对应路径中找不到资源,那么就会报错。
那不行啊,如果我们的程序不是在本机运行,那么难不成我们还要把资源一起和exe到处移动,多难看啊?于是就想,如何将资源一起打包进一个exe中呢。
首先,直接 Pyinstaller
打包,项目目录下会新增两个文件夹:dist、build。把这两个都删了。
是的,把这次打包出来的exe也删了。
Pyinstaller
打包后还会产生一个文件 XXX.spec,文件名就是打包的程序名。
这个 spec 文件中包含着打包的所有信息。他也许长这样:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['XXX.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
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='XXX',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['XXX.ico'],
)
我们打包的信息里面应有尽有,最上面的['XXX.py'],
是打包的程序名,最下面的 icon=['XXX.ico'],
是我们打包exe的图标。
既然我们在 Pyinstaller
时输入的信息里面都有,那么就可以利用这个文件,使我们的资源也加入打包队列。
binaries=[],
就是用于打包资源的。
可以看到它默认是空的,如果我们要打包资源,就往里面增加元素即可。具体格式的话是一个二元组(url1,url2)
例如我要将 logo.png 和 air_mitalic.ttf 一起打包进 exe 。其中,logo.png 和 air_mitalic.ttf 存放在项目的根目录,打包解压后我想把他们再次放到根目录,那么 spec 文件应该修改为
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['function_vision.py'],
pathex=[],
binaries=[('air_mitalic.ttf','.'),('logo.png','.')],
datas=[],
hiddenimports=[],
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='function_vision',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['logo.ico'],
)
修改好 spec 文件后,我们直接打包 spec 文件。在 cmd 中输入 Pyinstaller XXX.spec
即可。注意不要加 -F
或 -D
和其他打包 .py 文件时的命令。
打包完之后仍然会出现一个存放在 dist 文件夹中的exe文件,但是我发现运行他是还是资源路径错误报错。
最终,在这篇博客中找到了解决方法。
Pyinstaller打包用spec添加资源文件,亲测可用
原来是因为打包后的资源解压到了一个奇怪的临时目录下面,因此原程序找不到。
那么我们就修改源程序。怎么改,我们使用前人的经验,在程序中写下一个路径解析函数
def resurce_path(relative_path):
base_path=getattr(sys,'_MEIPASS',path.dirname(path.abspath(__file__)))
return path.join(base_path,relative_path)
每当在代码中需要调用资源的时候加上一个路径解析即可。
logo=pygame.image.load(resurce_path("logo.png"))
这样子,我们就可成功得到资源解压后所在的路径。
这个方法同样来自 Pyinstaller打包用spec添加资源文件,亲测可用,这里仅为引用。
亲测打包后的exe可以得到资源,这样子打包就免去了网上的一些 base64 转码法。