减小 pyinstaller exe 的大小
Posted
技术标签:
【中文标题】减小 pyinstaller exe 的大小【英文标题】:Reducing size of pyinstaller exe 【发布时间】:2018-05-21 09:24:54 【问题描述】:我有一个超过 40MB 的简单 pandas pyinstaller exe。
我的 exe 示例:
import collections
import csv
import selenium
import pandas
print('hi')
40MB 以上似乎有点过头了。
如何尽可能减少这种情况?
一种方法:
pyinstaller --onefile --exclude matplotlib --exclude scipy --exclude pandas --exclude numpy.py
但是考虑到排除列表有多大,这是不切实际的。
如何为 pyinstaller 选择一个文件夹以从中获取模块并排除其他所有内容,以便我可以拥有一个小型应用程序?
规格文件:
a = Analysis(['123.py'],
pathex=['C:\\Users\\AA\\ZZ'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='123',
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=True )
这也值得一提。默认情况下,Pyinstaller 不检测 pandas。
添加:
hiddenimports = ['pandas._libs.tslibs.timedeltas']
To: C:\Users\<NAME>\AppData\Local\Programs\Python\Python36\Lib\site-packages\PyInstaller\hooks
当使用多个可执行文件时,可能的solution 可能是将每个可执行文件链接到单独的文件夹或包含所有导入的可执行文件。
【问题讨论】:
如果您删除依赖项,exe 将无法运行您的脚本,还是我遗漏了什么? @FlorentB。 Pyinstaller 正在打包其他不需要的东西。另外,那个exe是40mb?我尝试对其进行UPX,但对我来说并没有太大变化。一定是做错了。 当我执行pyinstaller --onefile test.py
(test.py 包含您的示例)时,我得到一个大约 5mb 的可执行文件。
尝试使用 --onedir 选项而不是 --onefile,看看 pyinstaller 在 dist 文件夹中放了什么。
【参考方案1】:
尝试使用 virtualenv 设置您的环境,并仅在其中安装所需的库
关于使用虚拟环境的一些细节在这里:https://virtualenv.pypa.io/en/stable/
【讨论】:
我很犹豫要不要这样做,因为我最近因为文件损坏问题和 python 不得不重新安装我的整个操作系统。这安全吗?我会看看这是如何在虚拟盒子中进行的。 是的——它有点像python virtualbox——所有的包都安装在一个单独的虚拟环境中,并且不影响主要的python安装。删除它只是删除一个目录,并且您拥有多个具有不同库和版本组合的 virtualenvs 这种方法在我的例子中节省了 50% 的文件大小。我正在导入os
、pandas
、sqlalchemy
。
嗯,我在我的 virtualenv 中安装了 pytorch,它有 1.4 GB!!!现在,如果我不使用所有的 pytorch(只是一些库),是否可以通过这种方式减小 exe 文件的大小?
这个方法实际上让我的 exe 从 155 MB 变成了 10.4 MB。大声笑,谢谢。【参考方案2】:
对我来说,这是一个使用 pandas 的简单案例,它的 exe 很大。
虽然删除某些目录很有帮助,但 UPXING 也有很大帮助。
我把它减少了很多,默认情况下它没有这样做。
话虽如此,最终也是最重要的解决方案在这里讨论:Importing Python modules from a select location。所以有一个功能可以完成所有这些,但现在涉及到一些手动处理,因为:multipackage-bundles 已损坏。
现在是很多 exe 的简单解决方案
如果您有很多可执行文件,我强烈推荐这种方法:
pyinstaller -F abc.py --onedir (Have all imports of both scripts)
pyinstaller -F abd.py --onedir (Have all imports of both scripts)
现在将 abd.exe 以及任何其他外部脚本放在 abc.py 文件夹的一个目录中。确保它们的名称不同,否则只会运行一个脚本。
这非常有效,因为所有依赖项都在一个文件夹中。这是应该的。所以在这个例子中假设你有一个 40mb 的文件夹。对于之后的每个附加 exe,它只会是 +5mb(或 exe 有多大),而不是每个 40mb。
【讨论】:
【参考方案3】:python 解释器和所有导入的模块都包含在可执行文件中。
您可以尝试将要排除的模块添加到规范文件中Analysis
下的excludes
列表中。
您也可以尝试使用 UPX 压缩可执行文件。见A note on using UPX
【讨论】:
默认不升级吗?我有大量模块要排除,所以可能并不理想。除了给定目录之外,没有排除所有模块? 我以为它是自动升级的,我的错。类似:pyinstaller -F --upx-dir C:\Users\DD\Downloads\upx394w\upx394w\123\upx308w\upx.exe zz.spec 不起作用。【参考方案4】:我使用 Anaconda 环境,因此不能选择 virtualenv 解决方案。 我的方法是在我的规范文件中排除不必要的模块,例如:
在分析中(...)
excludes=['pandas', 'numpy'],
(这些模块极大地增加了文件的大小)
对于每个构建,我都使用这个调整后的规范文件来创建 exe。
pyinstaller "mySpec.spec" --distpath="<path>"
【讨论】:
【参考方案5】:我遇到了类似的问题并找到了解决方案。我使用了 Windows 终端预览。该程序允许创建各种虚拟环境,例如 Windows Power Shell(顺便说一句。Linux Ubuntu 也是如此。另外,值得注意的是:您可以在该程序中安装多个终端,甚至一次打开几个终端。非常酷的东西)。
在 Windows 终端预览中的 Windows Power Shell 中,我安装了所有必要的库,然后我打开了文件的路径并尝试使用此命令:
pyinstaller --onefile -w 'filename.py'
...但是,输出 exe
不起作用。出于某种原因,控制台说缺少一个库(我之前安装的)。我在模仿auto-py-to-exe
库中找到了解决方案。此 GUI 使用的命令是:
pyinstaller --noconfirm --onedir --console "C:/Users/something/filename.py"
而且这个效果很好。 我将输出 exe 程序的大小从 911MB 减小到 82.9MB !!!
顺便说一句。 911MB 是auto-py-to-exe
输出的大小。
我想知道为什么还没有人创建一个压缩器来读取代码,检查哪些库是代码的一部分,然后只将它们放入压缩器中。就我而言,auto-py-to-exe
可能加载了我曾经安装过的所有库。这可以解释这个压缩文件夹的大小。
有些人建议使用https://virtualenv.pypa.io/en/stable/,但在我看来,这个库非常困难,至少对我来说是这样。
【讨论】:
以上是关于减小 pyinstaller exe 的大小的主要内容,如果未能解决你的问题,请参考以下文章
Pyinstaller“无法执行脚本pyi_rth_pkgres”和缺少包
带有 Pyinstaller 的 PySide2:无法执行脚本 pyi_rth_pkgres