如何使用 pyinstaller 创建最小大小的可执行文件?

2024-04-13

我使用的是 Windows 10,安装了 anaconda,但我想使用 python 3.5 在一个新的、干净的最小环境中独立创建一个可执行文件。所以我做了一些测试:

测试1: 我在文件夹 testenv 中创建了一个 python 脚本 test1.py ,仅使用:

print('Hello World')

然后我创建了环境,安装了pyinstaller并创建了可执行文件

D:\testenv> python -m venv venv_test
...
D:\testenv\venv_test\Scripts>activate.bat
...
(venv_test) D:\testenv>pip install pyinstaller
(venv_test) D:\testenv>pyinstaller --clean -F test1.py

它创建了大约 6 Mb 的 test1.exe

测试2:我修改了test1.py如下:

import pandas as pd
print('Hello World')  

我在环境中安装了 pandas 并创建了新的可执行文件:

(venv_test) D:\testenv>pip install pandas
(venv_test) D:\testenv>pyinstaller --clean -F test1.py

Ant 它创建了我的 test1.exe,现在是230 Mb!!!

如果我运行命令

(venv_test) D:\testenv>python -V
Python 3.5.2 :: Anaconda custom (64-bit)

当我运行 pyinstaller 时,我收到一些我不理解的消息,例如:

INFO: site: retargeting to fake-dir 'c:\\users\\username\\appdata\\local\\continuum\\anaconda3\\lib\\site-packages\\PyInstaller\\fake-modules'

此外,我还收到有关 matplotlib 和其他与我的代码无关的模块的消息,例如:

INFO:   Matplotlib backend "pdf": added
INFO:   Matplotlib backend "pgf": added
INFO:   Matplotlib backend "ps": added
INFO:   Matplotlib backend "svg": added

我知道有一些相关的问题:减少 pyinstaller exe 的大小 https://stackoverflow.com/questions/47692213/reducing-size-of-pyinstaller-exe, 使用 pyinstaller 和 numpy 的可执行文件的大小 https://stackoverflow.com/questions/47769904/size-of-executable-using-pyinstaller-and-numpy但我无法解决这个问题,而且我担心我在 anaconda 方面做错了什么。

所以我的问题是: 我究竟做错了什么?我可以减小可执行文件的大小吗?


我接受了上面的答案,但我在这里发布了我为像我这样容易迷路的完全初学者一步一步所做的事情。

在开始之前,我发布了完整的 test1.py 示例脚本以及我实际需要的所有模块。如果它比原来的问题更复杂一点,我很抱歉,但也许这可以帮助某人。

test1.py 看起来像这样:

import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt
import matplotlib.image as image
import numpy as np
import os.path
import pandas as pd
import re   
    
from matplotlib.ticker import AutoMinorLocator 
from netCDF4 import Dataset
from time import time
from scipy.spatial import distance
from simpledbf import Dbf5
from sys import argv

print('Hello World')

我添加了 matplotlib.use('Agg') (因为我的实际代码正在创建数字)当 DISPLAY 未定义时使用 matplotlib 生成 PNG https://stackoverflow.com/questions/2801882/generating-a-png-with-matplotlib-when-display-is-undefined?answertab=active#tab-top

1)独立于anaconda安装新版本的python。

从以下位置下载Python:https://www.python.org/downloads/ https://www.python.org/downloads/安装时选择“将 python 添加到路径”并取消选择所有用户的安装启动器(我没有管理员权限) 检查我是否使用 CMD 的相同版本,只需编写python I get:

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017,
06:04:45) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.

2)从CMD创建并激活环境

D:\> mkdir py36envtest
...
D:\py36envtest>python -m venv venv_py36
...
D:\py36envtest\venv_py36\Scripts>activate.bat

3)在环境中安装脚本中需要的所有模块

使用以下命令确保它们与 python 版本兼容: (从在 Python 中导入时 Matplotlib 未被识别为模块 https://stackoverflow.com/questions/37581602/matplotlib-not-recognized-as-a-module-when-importing-in-python?answertab=active#tab-top)

(venv_py36) D:\py36envtest> python -m pip install nameofmodule

注意:就我而言,我还必须添加选项 --proxyhttps://00.000.000.00:0000 https://00.000.000.00:0000

例如,我使用 pyinstaller 的开发版本:

(venv_py36) D:\py36envtest> python -m pip install https://github.com/pyinstaller/pyinstaller/archive/develop.tar.gz

以及模块:pandas、matplolib、simpledbf、scipy、netCDF4。最后我的环境看起来像这样。

(venv_py36) D:\py36envtest> pip freeze
altgraph==0.15
cycler==0.10.0
future==0.16.0
macholib==1.9
matplotlib==2.1.2
netCDF4==1.3.1
numpy==1.14.0
pandas==0.22.0
pefile==2017.11.5
PyInstaller==3.4.dev0+5f9190544
pyparsing==2.2.0
pypiwin32==220
python-dateutil==2.6.1
pytz==2017.3
scipy==1.0.0
simpledbf==0.2.6
six==1.11.0
style==1.1.0
update==0.0.1

4)创建/修改.spec文件(当您运行pyinstaller时,它会创建一个.spec文件,您可以重命名)。

最初,我遇到了很多 ImportError: DLL load failed (尤其是对于 scipy) 和丢失模块错误,我通过这些帖子解决了这些错误:
持久(pickle)自定义 sklearn 管道的推荐方法是什么? https://stackoverflow.com/questions/47040099/what-is-the-recommended-way-to-persist-pickle-custom-sklearn-pipelines?answertab=active#tab-top
以及对此答案的评论:Pyinstaller 与 scipy.signal ImportError:DLL 加载失败 https://stackoverflow.com/questions/47065295/pyinstaller-with-scipy-signal-importerror-dll-load-failed?answertab=active#tab-top

我的 inputtest1.spec 最终看起来像这样:

# -*- mode: python -*-
options = [ ('v', None, 'OPTION')]
block_cipher = None


a = Analysis(['test1.py'],
             pathex=['D:\\py36envtest', 'D:\\py36envtest\\venv_py36\\Lib\\site-packages\\scipy\\extra-dll' ],
             binaries=[],
             datas=[],
             hiddenimports=['scipy._lib.messagestream',
                            'pandas._libs.tslibs.timedeltas'],
             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='test1',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True )

5)最后用命令制作可执行文件

(venv_py36) D:\py36envtest>pyinstaller -F --clean inputtest1.spec

我的 test1.exe 是 47.6 Mb,从 anaconda 虚拟环境创建的同一脚本的 .exe 是 229 Mb。

我很高兴(如果有更多建议也欢迎)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 pyinstaller 创建最小大小的可执行文件? 的相关文章

随机推荐