在PyInstaller中消除对matplotlib和qt的依赖(启动缓慢)

3
我正在使用pyinstaller将python脚本制作成一个文件夹可执行文件。启动速度相当慢。我的代码中的第一件事是打印“start”。当我运行可执行文件时,它需要超过10秒才能在屏幕上显示。我想缩短这个延迟时间。我猜想减少启动所需的dll数量会有帮助。
我注意到的一件事是,即使我不打算使用matplotlib和qt5 dll,它们也被复制到输出文件夹中。在我的代码中,我没有依赖于这些库。我的导入是:
import os
import sys
import argparse
import numpy as np
import logging
import json
from element import Square, Slanted
from skimage import measure
from skimage.segmentation import clear_border
try:
    from skimage import filters
except:
    from skimage import filter as filters

from scipy import ndimage 
from scipy.ndimage.filters import gaussian_filter, median_filter
from scipy.optimize import curve_fit
from enum import Enum
import time

pyinstall输出的第一部分,直到开始提到matplotlib为止,如下所示:

212 INFO: PyInstaller: 3.2.1
213 INFO: Python: 3.5.2
214 INFO: Platform: Windows-7-6.1.7601-SP1
249 INFO: wrote x:\script.spec
255 INFO: UPX is not available.
308 INFO: Extending PYTHONPATH with paths
['x:\\', 'x:\\script']
310 INFO: checking Analysis
311 INFO: Building Analysis because out00-Analysis.toc is non existent
312 INFO: Initializing module dependency graph...
346 INFO: Initializing module graph hooks...
352 INFO: Analyzing base_library.zip ...
6794 INFO: running Analysis out00-Analysis.toc
7585 INFO: Caching module hooks...
7596 INFO: Analyzing x:\script.py
10819 INFO: Processing pre-find module path hook   distutils
13057 INFO: Processing pre-find module path hook   site
13061 INFO: site: retargeting to fake-dir 'c:\\anaconda3\\envs\\myeenv\\lib\\site-packages\\PyInstaller\\fake-modules'
20369 INFO: Processing pre-safe import module hook   win32com
27275 INFO: Processing pre-safe import module hook   six.moves
38245 INFO: Loading module hooks...
38247 INFO: Loading module hook "hook-pydoc.py"...
38250 INFO: Loading module hook "hook-xml.dom.domreg.py"...
38253 INFO: Loading module hook "hook-xml.py"...
38256 INFO: Loading module hook "hook-distutils.py"...
38265 INFO: Loading module hook "hook-pytz.py"...
38434 INFO: Loading module hook "hook-numpy.core.py"...
38832 INFO: MKL libraries found when importing numpy. Adding MKL to binaries
38837 INFO: Loading module hook "hook-_tkinter.py"...
40127 INFO: checking Tree
40129 INFO: Building Tree because out00-Tree.toc is non existent
40131 INFO: Building Tree out00-Tree.toc
40264 INFO: checking Tree
40266 INFO: Building Tree because out01-Tree.toc is non existent
40266 INFO: Building Tree out01-Tree.toc
40301 INFO: Loading module hook "hook-PyQt5.QtCore.py"...
40918 INFO: Loading module hook "hook-matplotlib.py"...
43519 INFO: Loading module hook "hook-win32com.py"...

我如何确定是哪个库给我提供了matplotlib/qt5依赖项?有什么其他的方法可以改善启动时间吗?
我尝试使用:
pyinstaller script.py --exclude-module matplotlib,qt5

但是它仍然开始包括matplotlib.backends等...

编辑

看起来skimage.segmentation正在包含matplotlib...

Traceback (most recent call last):
  File "myenv\script.py", line 11, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\segmentation\__init__.py", line 6, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\segmentation\boundaries.py", line 5, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\morphology\__init__.py", line 1, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\morphology\binary.py", line 6, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\morphology\misc.py", line 5, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\morphology\selem.py", line 3, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\draw\__init__.py", line 1, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\draw\draw.py", line 6, in <module>
  File "c:\anaconda3\envs\myenv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\skimage\_shared\_geometry.py", line 4, in <module>
ImportError: No module named 'matplotlib'
Failed to execute script myenv

编辑2

小测试。使用pyinstaller制作了以下脚本的单文件可执行程序:

import numpy as np
print(np.array([0]))

运行时间约为6秒。今天早上我意识到我正在从一个samba挂载中运行,并且这可能会显著影响启动时间。相同的可执行文件在本地启动时只需要0.7秒!虽然我仍然有兴趣缩小发布大小(> 500MB)。


1
我的应用程序有许多依赖项,例如您所列出的(如wxpython、numpy、scipy、matplotlib等),但在Win7上启动时间不到1秒。我使用py2exe打包它,与其他几个打包工具比较启动速度时,py2exe是我应用程序的最佳选择。因为您提到了dlls,我假设这也是Windows平台。 - otterb
正确,使用Windows 7。感谢您建议使用py2exe。我会去尝试一下。今天早上我也意识到我是从Samba挂载运行的。我将使用本地副本进行一些测试并更新上面的问题。 - Goosebumps
只是一个小小的(非常晚的)更新。Samba 挂载也对启动时间产生了非常不好的影响。在本地复制文件更快。 - Goosebumps
1个回答

4

排除模块的问题在于,pyinstaller将--exclude-module命令行参数解释为一个包,因此会出现问题。

pyinstaller script.py --exclude-module matplotlib,qt5

.spec文件中,使用excludes=['matplotlib,qt5']会排除这两个包。如果要排除这两个包,需要将它们分开写:
pyinstaller script.py --exclude-module matplotlib --exclude-module qt5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接