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

时间:2018-02-05 18:49:49

标签: python pandas anaconda virtualenv pyinstaller

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

TEST1: 我在文件夹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

我知道有一些相关的问题: Reducing size of pyinstaller exesize of executable using pyinstaller and numpy 但我无法解决问题,我担心我对蟒蛇做错了。

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

2 个答案:

答案 0 :(得分:19)

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

在开始之前,我发布完整的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')(因为我的实际代码是创建数字) Generating a PNG with matplotlib when DISPLAY is undefined

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

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

2)从CMD

创建并激活环境
D:\> mkdir py36envtest
...
D:\py36envtest>python -m venv venv_py36
...
D:\py36envtest\venv_py36\Scripts>activate.bat

3)在环境中安装脚本

中所需的所有模块

使用以下命令确保它们与python版本兼容: (来自Matplotlib not recognized as a module when importing in Python

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

注意:在我的情况下,我还必须添加选项--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

和模块: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加载失败(尤其是scipy)和模块错误,我解决了这些帖子: What is the recommended way to persist (pickle) custom sklearn pipelines?
以及对这个答案的评论: Pyinstaller with scipy.signal ImportError: DLL load failed

我的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。

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

答案 1 :(得分:2)

问题是你不应该使用虚拟环境,特别是不应该使用anaconda。请下载默认的python 32位并仅使用必要的模块。然后按照链接中提供的步骤进行操作,这绝对应该解决。

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

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