19

我已经开始在 Py2Exe 上使用 Pyinstaller。但是,我很快就遇到了问题。如何排除我不想要的模块,以及如何查看包含在单个可执行文件中的模块?

我可以从我的 Python 安装中的 DLL 文件夹中删除一些pyddll文件,因此 Pyinstaller 找不到,因此不包含它们。我真的不想对所有模块都这样做,因为它会变得非常艰巨。

我确实尝试编辑 Pyinstaller 制作的规范文件。

a.binaries - [('ssl','pydoc',)],

但是文件的大小保持不变,所以我断定这不起作用。

那么如何查看 Pyinstaller 包含哪些模块以及如何排除那些我不想要的模块?

4

5 回答 5

28

只是在我使用它们时总结一下这里的选项。

PyInstaller TOC - 是,如文档所述:

TOC 似乎是形式为(名称、路径、类型代码)的元组列表。事实上,它是一个有序集合,而不是一个列表。TOC 不包含重复项,其唯一性仅基于名称。

换句话说,简单地说:

a_toc = [('uname1','/path/info','BINARY'),('uname2','/path/to','EXTENSION')...]

因此,在您的 .spec 文件中 - 一旦您获得了脚本的分析结果 - 您可以通过以下任一方式进一步修改相应的 TOC:

  • 对于特定文件/模块,使用差异 (-) 和交集 (+) 操作来修改 TOC。*

  • 对于添加/删除文件/模块列表,遍历 TOC 并与模式匹配代码进行比较。

(*顺便说一句,要使差异起作用,您似乎必须显式转换为TOC()并注意,由于它只是唯一定义集合元素的名称,因此您只需要指定 - 因此('sqlite3', None, None)等等)

下面是一个说明性示例(取自 .spec 文件)——无论好坏——我删除了对 scipy、IPython 和 zmq 的所有引用;删除特定的 sqlite、tcl/tk 和 ssl .DLL;插入缺少的 opencv .DLL;最后删除除matplotlib之外的所有数据文件夹......

当 .pyc 文件尝试加载预期的 .DLL 时,生成的 Pyinstaller .exe 是否可以工作尚无定论:-/

# Manually remove entire packages...

a.binaries = [x for x in a.binaries if not x[0].startswith("scipy")]

a.binaries = [x for x in a.binaries if not x[0].startswith("IPython")]

a.binaries = [x for x in a.binaries if not x[0].startswith("zmq")]

# Target remove specific ones...

a.binaries = a.binaries - TOC([
 ('sqlite3.dll', None, None),
 ('tcl85.dll', None, None),
 ('tk85.dll', None, None),
 ('_sqlite3', None, None),
 ('_ssl', None, None),
 ('_tkinter', None, None)])

# Add a single missing dll...

a.binaries = a.binaries + [
  ('opencv_ffmpeg245_64.dll', 'C:\\Python27\\opencv_ffmpeg245_64.dll', 'BINARY')]

# Delete everything bar matplotlib data...

a.datas = [x for x in a.datas if
 os.path.dirname(x[1]).startswith("C:\\Python27\\Lib\\site-packages\\matplotlib")]
于 2013-07-11T13:48:16.847 回答
11

尽管可能已经给出了更好的解决方案,但还有另一种方法:您可以将 '--exclude-module' 属性与 'pyinstaller' 命令一起使用,但是当您必须排除许多模块时,此方法相当冗长。

为了使工作更容易,您可以编写一个包含所有值得跳过的库的批处理脚本文件,并一次又一次地使用它。

像这样的东西:

@echo off

pyinstaller --onefile a.py --exclude-module matplotlib ^
                           --exclude-module scipy ^
                           --exclude-module setuptools ^
                           --exclude-module hook ^
                           --exclude-module distutils ^
                           --exclude-module site ^
                           --exclude-module hooks ^
                           --exclude-module tornado ^
                           --exclude-module PIL ^
                           --exclude-module PyQt4 ^
                           --exclude-module PyQt5 ^
                           --exclude-module pydoc ^
                           --exclude-module pythoncom ^
                           --exclude-module pytz ^
                           --exclude-module pywintypes ^
                           --exclude-module sqlite3 ^
                           --exclude-module pyz ^
                           --exclude-module pandas ^
                           --exclude-module sklearn ^
                           --exclude-module scapy ^
                           --exclude-module scrapy ^
                           --exclude-module sympy ^
                           --exclude-module kivy ^
                           --exclude-module pyramid ^
                           --exclude-module opencv ^
                           --exclude-module tensorflow ^
                           --exclude-module pipenv ^
                           --exclude-module pattern ^
                           --exclude-module mechanize ^
                           --exclude-module beautifulsoup4 ^
                           --exclude-module requests ^
                           --exclude-module wxPython ^
                           --exclude-module pygi ^
                           --exclude-module pillow ^
                           --exclude-module pygame ^
                           --exclude-module pyglet ^
                           --exclude-module flask ^
                           --exclude-module django ^
                           --exclude-module pylint ^
                           --exclude-module pytube ^
                           --exclude-module odfpy ^
                           --exclude-module mccabe ^
                           --exclude-module pilkit ^
                           --exclude-module six ^
                           --exclude-module wrapt ^
                           --exclude-module astroid ^
                           --exclude-module isort

或者您可以随时使用新的 python 安装,只需在安装时更改新 python 安装的路径。

于 2019-06-03T07:33:34.097 回答
5

你可以试试这个,它比 .bat 脚本要好得多:

# Just add or remove values to this list based on the imports you don't want : )
excluded_modules = [
    'numpy',
    'jedi',
    'PIL',
    'psutil',
    'tk',
    'ipython',
    'tcl',
    'tcl8',
    'tornado'
]

append_string = ''
for mod in excluded_modules:
    append_string += f' --exclude-module {mod}'

# Run the shell command with all the exclude module parameters
os.system(f'pyinstaller myfile.py --noconfirm {append_string}')

希望你觉得这个有用!

于 2021-01-06T17:50:24.343 回答
4

您可以使用 Python 操作由 Analysis 类生成的列表。请注意,这些是 PyInstaller 的 TOC 格式。

a = Analysis(...)
...
# exclude anything from the Windows system dir       
a.binaries = [x for x in a.binaries if not 
              os.path.dirname(x[1]).startswith("C:\\Windows\\system32")]
于 2011-10-11T23:16:11.177 回答
4

自己寻找答案

我见过很多这样的问题,但是没有人教你如何自己调试。

pyinstaller 的文档可能对初学者有用,但是一旦您需要更多...

个人认为 pyinstaller 文档不友好(示例太少)并且缺少更新。

例如,文档显示 pyinstaller 的版本是 3.2。(3.5现已上市(2019/10/5))现在(2020-12-15)他们都有相同的版本

我想说你应该从源代码中找到答案

开始方式

  • 创建一个脚本文件(例如 run_pyinstaller.py),如下所示:
# run_pyinstaller.py

from PyInstaller.__main__ import run
run()
  • 在运行此脚本之前,您可以分配参数,例如“ --clean your.spec

  • 设置断点{env_path}/Lib/site-packages/PyInstaller/building/build_main.py -> def build(...) ... -> exec(code, spec_namespace)如下:

    注意:如果你没有使用虚拟环境,实际路径应该是{Python} /Lib/site-packages/PyInstaller/building/ build_main.py

在此处输入图像描述

  • 最后,你跑到这里并按下 step into 按钮。您将进入 .spec 文件

然后您可以查看您感兴趣的任何变量。

此外,您将了解更多关于 pyinstaller.exe 实际执行的操作。

例如,您了解 TOC 的类是继承到列表,并从PyInstaller.building.datastruct.py中查看比文档更多的细节

在此处输入图像描述

最终,您可以使用任何 python 方式进行设置a.binariesa.datas这就是您真正想要的

相关文件位置

from PyInstaller.building.datastruct import TOC, Tree
from PyInstaller.building.build_main import Analysis
from PyInstaller.building.api import EXE, PYZ, COLLECT, PKG, MERGE
于 2019-10-05T09:04:36.457 回答