Pyinstaller在编译时排除子模块

2024-06-30 08:19:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经使用PyQt5开发了UI,现在我正在使用Pyinstaller将代码转换为独立的应用程序,但问题是文件大小越来越大(接近250MB)。我可以减小文件的大小,但不包括不必要的PyQt5导入。 以下是我使用过的图书馆-

from PyQt5 import QtCore, QtGui, QtWidgets
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
import os,sys
from mat4py import loadmat
from matplotlib import pyplot as plt

PyQt5库有以下许多子模块(QtCore、QtGui、QtWidgets、QtMultimedia、QtBluetooth、QtNetwork、QtPositioning、Enginio、QTWebSocket、QtWebKit、QtWebKitWidgets、QtXml、QtSvg、QtSql、QtTest),其中我只使用了QtCore、QtGui和QtWidgets

类似地,库matplotlib包含许多我正在使用pyplot的模块

我想跳过程序不使用的模块,这样可以减小可执行文件的大小

我的pyinstaller规范文件-

import sys
sys.setrecursionlimit(3000)

block_cipher = None

a = Analysis(['ReadMAT.py'],
             pathex=['C:\\Users\\Sekhar\\Documents\\PythonScripts\\RXP\\ReadMAT'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='ReadMAT',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False, icon='ReadMAT.ico')

如何跳过不会进入编译过程的子模块。如何减小可执行文件的文件大小


Tags: 模块文件fromimportfalsetkinterassys
1条回答
网友
1楼 · 发布于 2024-06-30 08:19:54

PyInstaller对每个包都有一个hook机制,它处理包所需的二进制文件

对于一些众所周知的库,如Qt,它实现了一个高效的钩子文件,只检索必要的二进制文件。但是,如果要排除某些零件,则需要通过使用exclude命令或操纵钩子文件自己进行排除:

  1. 通过使用^{}排除不必要的模块。通常,这就足够了

  2. 通过修改特定的钩子文件并删除不需要的二进制文件

    例如,在Qt的hook文件(<Pyinstaller_path>/utils/hooks/qt.py)中,有一个名为_qt_dynamic_dependencies_dict的变量,它包含位于<qt_installation_path>/Qt/bin中的所有二进制文件,因此您可以删除不需要的每个二进制文件

    稍后,在一个名为get_qt_binaries的函数中,您可以删除其他Qt二进制文件,比如opengl32sw.dll

例如:

_qt_dynamic_dependencies_dict = {
    ## "lib_name":              (.hiddenimports,           translations_base,  zero or more plugins...)
    # I've removed qt5bluetooth with commenting below line
    #"qt5bluetooth":             (".QtBluetooth",           None,               ),  # noqa: E241,E202
    "qt5concurrent":            (None,                     "qtbase",           ),
    ...
}
...

def get_qt_binaries(qt_library_info):
    binaries = []
    angle_files = ['libEGL.dll', 'libGLESv2.dll', 'd3dcompiler_??.dll']
    binaries += find_all_or_none(angle_files, 3, qt_library_info)

    # comment the following two lines to exclude the `opengl32sw.dll`
    # opengl_software_renderer = ['opengl32sw.dll']
    # binaries += find_all_or_none(opengl_software_renderer, 1, qt_library_info)

    # Include ICU files, if they exist.
    # See the "Deployment approach" section in ``PyInstaller/utils/hooks/qt.py``.
    icu_files = ['icudt??.dll', 'icuin??.dll', 'icuuc??.dll']
    binaries += find_all_or_none(icu_files, 3, qt_library_info)

    return binaries

相关问题 更多 >