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

esp*_*tte 9 python virtualenv pyinstaller pandas anaconda

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

TEST1:我在文件夹testenv中创建了一个python脚本test1.py,只有:

print('Hello World')
Run Code Online (Sandbox Code Playgroud)

然后我创建了环境,安装了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
Run Code Online (Sandbox Code Playgroud)

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

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

import pandas as pd
print('Hello World')  
Run Code Online (Sandbox Code Playgroud)

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

(venv_test) D:\testenv>pip install pandas
(venv_test) D:\testenv>pyinstaller --clean -F test1.py
Run Code Online (Sandbox Code Playgroud)

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

如果我运行命令

(venv_test) D:\testenv>python -V
Python 3.5.2 :: Anaconda custom (64-bit)
Run Code Online (Sandbox Code Playgroud)

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

INFO: site: retargeting to fake-dir 'c:\\users\\username\\appdata\\local\\continuum\\anaconda3\\lib\\site-packages\\PyInstaller\\fake-modules'
Run Code Online (Sandbox Code Playgroud)

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

INFO:   Matplotlib backend "pdf": added
INFO:   Matplotlib backend "pgf": added
INFO:   Matplotlib backend "ps": added
INFO:   Matplotlib backend "svg": added
Run Code Online (Sandbox Code Playgroud)

我知道有一些相关的问题: 减少pyinstaller exe文件的大小,使用pyinstaller和numpy的可执行文件的大小 ,但我没能解决问题,恐怕我做错了什么关于蟒蛇.

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

esp*_*tte 28

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

在开始之前,我发布完整的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')
Run Code Online (Sandbox Code Playgroud)

我添加了matplotlib.use('Agg')(因为我的实际代码正在创建数字) 当DISPLAY未定义时,使用matplotlib生成PNG

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

下载python来自:https: //www.python.org/downloads/ 安装选择'添加python到路径'并取消选择所有用户的安装启动器(我没有管理员权限)检查我使用的是CMD中的相同版本,只写python我得到:Python 3.6.4(v3.6.4:d48eceb,2017年12月19日,06:04:45)[MSC v.1900 32位(英特尔)]在win32上输入"help","copyright","信用"或"许可"以获取更多信息.

2)从CMD创建并激活环境

D:\> mkdir py36envtest
...
D:\py36envtest>python -m venv venv_py36
...
D:\py36envtest\venv_py36\Scripts>activate.bat
Run Code Online (Sandbox Code Playgroud)

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

使用以下命令确保它们与python版本兼容:( 在使用Python导入时,Matplotlib不被识别为模块)

(venv_py36) D:\py36envtest> python -m pip install nameofmodule
Run Code Online (Sandbox Code Playgroud)

注意:在我的情况下,我还必须添加选项--proxy https://00.000.000.00:0000

对于示例,我使用了py安装程序的开发版本:

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

和模块: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
Run Code Online (Sandbox Code Playgroud)

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

最初我得到了很多ImportError:DLL加载失败(特别是对于scipy)和丢失的模块错误我解决了这些帖子:
建议的方法是持久化(pickle)自定义sklearn管道?
以及对此答案的评论: Pyinstaller with scipy.signal ImportError:DLL加载失败

我的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 )
Run Code Online (Sandbox Code Playgroud)

5)最后使用命令生成可执行文件

(venv_py36) D:\py36envtest>pyinstaller -F --clean inputtest1.spec
Run Code Online (Sandbox Code Playgroud)

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

我很高兴(如果有更多建议,欢迎他们)

  • Numpy 可以使用或不使用优化库(MKL、BLAS 等)来构建。因此,对于较小的可执行文件(可能执行计算速度较慢),您可以构建/安装 numpy 的普通版本,例如,来自 [Python 扩展包的非官方 Windows 二进制文件](https://www.lfd.uci.edu/~ gohlke/pythonlibs/#numpy)。此更改将我的可执行文件大小减少了 11MB。 (2认同)

Dra*_*eow 3

问题是你不应该使用虚拟环境,尤其是 anaconda。请下载默认的 python 32 位并仅使用必要的模块。然后按照链接中提供的步骤操作,这肯定可以解决问题。

尽管您创建了一个虚拟环境,但您确定您的规范文件没有链接到旧的 Anaconda 条目吗?

如果这一切都失败了,那么提交一个错误,因为这很奇怪。

  • @esperluette 想一想。Anaconda 是一个大型图书馆。除了 Anaconda 库之外,还有什么可能导致您的文件如此之大。默认 python 32 位相当于 35mb?我强烈建议你至少尝试一个单独的 python 32 位,看看是否有帮助。如果没有,这可能是一个错误。当我使用 Anaconda 时,我的 pyinstaller 文件总是很大。另外,Anaconda 安装并不总是与某些 python 库兼容。我发现 32 位 python 更兼容并且更小。至少可能值得一试,但我可能是错的。希望这可以帮助。 (2认同)

归档时间:

查看次数:

10350 次

最近记录:

5 年,11 月 前