且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Python:排除模块 Pyinstaller

更新时间:2023-12-05 08:47:16

这里只是总结一下我使用的选项.

Just to summarise the options here as I use them.

PyInstaller TOC - 正如文档所说:

PyInstaller TOC's - are, as the documentation says:

TOC 似乎是形式为 (name, path,类型代码).实际上,它是一个有序集,而不是一个列表.TOC 不包含重复,唯一性仅基于名称.

A TOC appears to be a list of tuples of the form (name, path, typecode). In fact, it's an ordered set, not a list. A TOC contains no duplicates, where uniqueness is based on name only.

换句话说,就是:

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

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

So, in your .spec file - once you've got the Analysis results of the script - you can then further modify the respective TOC's by either:

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

  • For specific files/modules use the difference (-) and intersection (+) operations to modify a TOC. *

为了添加/删除文件/模块的列表,遍历 TOC 并与模式匹配代码进行比较.

For adding/removing lists of files/modules iterate over the the TOC and compare with pattern matching code.

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

(* As an aside, for the difference to work it seems you must explicitly cast to TOC() and note that since it is only the name that uniquely defines the element of the set, you only need to specify that - hence ('sqlite3', None, None) etc.)

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

An illustrative example (taken from a .spec file) is below where - for better or worse - I remove all references to scipy, IPython and zmq; delete specific sqlite, tcl/tk and ssl .DLL's; insert a missing opencv .DLL; and finally remove all data folders found apart from matplotlib ones...

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

Whether the resulting Pyinstaller .exe will then work when an .pyc file tries to load an expected .DLL is moot:-/

# 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")]