为啥 Python 3 的 cx_freeze 将一个项目打包成 8000+ 个文件,而 Python 2 的 cx_freeze 将同一个项目打包成 25 个文件?

Posted

技术标签:

【中文标题】为啥 Python 3 的 cx_freeze 将一个项目打包成 8000+ 个文件,而 Python 2 的 cx_freeze 将同一个项目打包成 25 个文件?【英文标题】:Why does cx_freeze for Python 3 packs a project into 8000+ files whereas cx_freeze for Python 2 packed the same project in 25 files?为什么 Python 3 的 cx_freeze 将一个项目打包成 8000+ 个文件,而 Python 2 的 cx_freeze 将同一个项目打包成 25 个文件? 【发布时间】:2020-06-15 20:50:27 【问题描述】:

假设numpy_example.py 是:

import numpy as np
a = np.array([1, 2, 3])
print(a)

使用 Python 2.7.9,使用 cxFreeze 4.3.3 生成可执行文件,其中:

"C:\python27\python.exe" "C:\python27\Scripts\cxfreeze" numpy_example.py 
   --target-dir=.\cxfreeze_x64_py2 --base-name=Win32GUI 
   --target-name=test.exe --exclude-modules=Tkinter,scipy,Crypto,_ssl,bz2,_yaml 
   --include-modules=lxml._elementpath

提供了 25 个文件(仅 .dll.pyd.exe 文件),总共 71 MB,没有子文件夹:

使用 Python 3.7.6,使用 cxFreeze 6 生成可执行文件,使用相同的命令行命令会产生总共 8533 个文件,总共 374 MB

特别是,Lib 子文件夹包含许多未用于此项目的库:

此外,在 Python 2 版本中,Numpy 被打包到 9 个 .pyd 文件中(仅此而已),而在 Python 3 版本中,它被拆分为许多文件和子文件夹。

问题:cx_freeze 发生了什么变化,导致打包效率降低?

以及如何在 Python 3 中使用cx_freeze 获得与使用 Python 2 类似的包装?

【问题讨论】:

相关问题:github.com/anthony-tuininga/cx_Freeze/issues/675 我的工作流程是拥有一个单独的构建环境,其中只安装了运行脚本所需的最少软件包。这很可能不是一个万能的解决方案,但在我的情况下是一个可用的解决方法。 numpy 有多少依赖项 【参考方案1】:

这似乎是答案:这是一个功能,因为 cx_freeze 5.0: https://cx-freeze.readthedocs.io/en/latest/releasenotes.html#version-5-0-november-2016

添加了对将包存储在文件系统而不是 zip 文件中的支持。有许多软件包假设它们是在文件系统中找到的,如果在 zip 文件中找到它们,则会产生奇怪的错误。现在默认将包存储在文件系统中,但是如果已知它们在放置时行为正确,则可以使用一种方法将包放置在 zip 文件中。 (Issue #73)

链接:Cx_Freeze build is not including python libraries in zip file

【讨论】:

【参考方案2】:

正如您在自己的答案中指出的那样,这似乎是所需的功能。还有其他可以编译成单个可执行文件的包。

我假设你只想使用 cxfreeze,如果你知道你的程序不需要需要哪些包,你可以像以前一样简单地用--exclude-modules 标志列出所有这些包。您可以通过构建应用程序通过反复试验过滤掉包,然后一一重命名lib 目录中包含的库,将任何不必要的包添加到排除列表中。通过这种方式,我能够将 numpy 示例从 3500~ 个文件减少到~1000 个。

您可以使用distutils 功能,我发现它在尝试减小最终包大小时更容易。

from cx_Freeze
import setup, Executable
import sys

build_exe_options = 
  "excludes": ["tkinter", ...your excludes here...],
  "optimize": 0


setup(
  name = "TestProgram",
  version = "0.1",
  description = "MyDescription",
  options = 
    "build_exe": build_exe_options
  ,
  executables = [Executable("main.py",
    base = ("Win32GUI"
      if sys.platform == "win32"
      else None))]
)
py setup.py build

最后,cxfreeze 常见问题解答有一个关于创建single file 的问题,虽然这不是你想要的,但它声明使用IExpress 创建一个自解压存档(或 7zip),这可能很有用如果包装尺寸是主要问题,请给您。

【讨论】:

感谢您的回答。请注意,我不想创建单个文件可执行文件,我只想尽可能将 Python 2 中的 8000 多个文件减少到 25 个文件。跨度> 我是这么认为的,但我在其中添加了这一点,供其他正在从 cxfreeze 寻找它的人使用 :-)

以上是关于为啥 Python 3 的 cx_freeze 将一个项目打包成 8000+ 个文件,而 Python 2 的 cx_freeze 将同一个项目打包成 25 个文件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 cx_Freeze 中创建线程池?

cx_Freeze:主脚本中的 Python 错误。 Python 3.6 + cx_Freeze

pyodbc python 3.4的cx_freeze错误

Cx_freeze 不适用于带有 Python 3.6.2 的 Win 10

使用 Python 3.2 和 cx_Freeze 创建 Windows 可执行文件

Python 3.2:cx_freeze 编译我的程序,但处于调试模式