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

问题描述 投票:6回答:2

我在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,但我无法解决问题,我担心我对anaconda做错了什么。

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

python pandas anaconda virtualenv pyinstaller
2个回答
2
投票

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

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

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


20
投票

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

在开始之前,我发布完整的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) Install a new version of python independently from anaconda.

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

2) Create and activate the environment, from CMD

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

3) Install in the environment all the modules needed in the script

使用以下命令确保它们与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) Create/modify the .spec file (when you run pyinstaller it creates a .spec file, you can rename).

最初我得到了很多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) Finally make the executable with the command

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.