Python 的 zipapp:构建可执行的 Zip 应用程序

Yuchuan 发表于 2021/11/24 19:45:56 2021/11/24
【摘要】 拥有一种快速有效的方式来分发您的 Python 可执行应用程序可以在满足最终用户的需求方面发挥重要作用。Python Zip 应用程序为您提供了一种有效且易于访问的解决方案,用于捆绑和分发可立即运行的应用程序。您可以使用zipappPython 标准库快速创建您自己的可执行 Zip 应用程序并将它们传递给您的最终用户。

目录

Python Zip 应用程序是一个快速而酷的选项,您可以将可执行应用程序捆绑并分发到一个可立即运行的文件中,这将使您的最终用户体验更加愉快。如果您想了解 Python 应用程序以及如何使用zipapp标准库创建它们,那么本教程适合您。

您将能够创建 Python Zip 应用程序,作为将您的软件产品分发给最终用户和客户的一种快速且可访问的方式。

在本教程中,您将学习:

  • 什么是Python的应用邮编
  • Zip 应用程序如何在内部工作
  • 如何构建Python Zip 应用程序zipapp
  • 什么是独立的 Python Zip 应用程序以及如何创建它们
  • 如何使用命令行工具手动创建 Python Zip 应用程序

您还将了解一些用于创建 Zip 应用程序的第三方库,这些库克服了zipapp.

为了更好地理解本教程,您需要了解如何构建 Python 应用程序布局运行 Python 脚本构建 Python 包、使用Python 虚拟环境以及使用pip. 您还需要习惯使用命令行或终端。

Python Zip 应用程序入门

Python 生态系统中最具挑战性的问题之一是找到一种有效的方法来分发可执行应用程序,例如图形用户界面 (GUI)命令行界面 (CLI)程序。

编译的编程语言,如CC++Go,可以生成可执行文件,您可以直接在不同的操作系统和体系结构上运行。这种能力使您可以轻松地向最终用户分发软件。

然而,Python 不是这样工作的。Python 是一种解释型语言,这意味着您需要一个合适的 Python 解释器来运行您的应用程序。没有直接的方法可以生成不需要解释器运行的独立可执行文件。

有许多解决方案旨在解决这个问题。您会找到诸如PyInstallerpy2exepy2appNuitka等工具。这些工具允许您创建可以分发给最终用户的独立可执行应用程序。但是,设置这些工具可能是一个复杂且具有挑战性的过程。

有时您不需要那种额外的复杂性。您只需要从脚本或小程序构建一个可执行的应用程序,即可快速将其分发给最终用户。如果您的应用程序足够小并且使用纯 Python 代码,那么您可以使用Python Zip 应用程序提供良好的服务。

什么是 Python Zip 应用程序?

PEP 441 – 改进 Python ZIP 应用程序支持使Python Zip 应用程序的思想、术语和规范正式化。这种类型的应用程序由一个使用ZIP 文件格式的文件组成,并包含 Python 可以作为程序执行的代码。这些应用程序依赖于 Python 从 ZIP 文件中运行代码的能力,这些 ZIP 文件__main__.py的根有一个模块,作为入口点脚本工作。

2.6 和 3.0版本以来,Python 已经能够从 ZIP 文件运行脚本。实现这一目标的步骤非常简单。您只需要一个 ZIP 文件__main__.py,其根目录下有一个模块。然后,您可以将该文件传递给 Python,Python 将其添加到程序中sys.path__main__.py作为程序执行。将应用程序的存档放入sys.path允许您通过 Python 的导入系统访问其代码。

作为所有工作原理的快速示例,假设您在类 Unix操作系统上,例如 Linux 或 macOS,并运行以下命令:

$ echo 'print("Hello, World!")' > __main__.py

$ zip hello.zip __main__.py
  adding: __main__.py (stored 0%)

$ python ./hello.zip
Hello, World!

您可以使用该echo命令创建一个__main__.py包含代码的文件print("Hello, World!")。然后使用该zip命令归档__main__.pyhello.zip. 完成后,您可以hello.zip通过将文件名作为参数传递给python命令来作为程序运行。

为了总结 Python Zip 应用程序的内部结构,您需要一种方法来告诉操作系统如何执行它们。ZIP 文件格式允许您在 ZIP 存档的开头添加任意数据。Python Zip 应用程序利用该功能在应用程序的存档中包含标准的Unix shebang行:

#!/usr/bin/env python3

在 Unix 系统上,这一行告诉操作系统使用哪个程序来执行手头的文件,以便您可以直接运行该文件而无需python命令。在 Windows 系统上,Python 启动器正确理解 shebang 行并为您运行 Zip 应用程序。

即使使用 shebang 行,您始终可以通过将应用程序的文件名作为参数传递给python命令来执行 Python Zip 应用程序。

总之,要构建 Python Zip 应用程序,您需要:

  • 使用标准 ZIP 文件格式并在其根目录包含一个__main__.py模块的存档
  • 一个可选的shebang 行,指定合适的Python 解释器来运行应用程序

除了__main__.py模块之外,应用程序的 ZIP 文件还可以包含 Python模块和包以及任何其他任意文件。但是,只有.py.pyc.pyo文件可通过导入系统直接使用。换句话说,您可以在应用程序文件中打包.pyd.so.dll文件,但除非将它们解压缩到文件系统中,否则将无法使用它们。

注:从执行代码的可能性.pyd.so以及.dll文件存储在一个ZIP文件是操作系统的限制。这种限制使得很难创建zip应用程序,船舶和使用.pyd.so以及.dll文件。

Python 生态系统充满了用 C 或 C++ 编写的有用的库和工具,以保证速度和效率。即使您可以将这些库中的任何一个捆绑到 Zip 应用程序的存档中,您也无法直接从那里使用它们。您需要将库解压缩到您的文件系统中,然后从该新位置访问其组件。

PEP 441 提出.pyz.pyzw作为Python Zip 应用程序的文件扩展名。的.pyz分机识别控制台或命令行应用程序,而.pyzw扩展名是指窗或GUI应用程序

在 Unix 系统上,.pyz如果您更喜欢 CLI 应用程序的简单命令名称,则可以删除扩展名。在 Windows 上,.pyz.pyzw文件是可执行文件,因为 Python 解释器将它们注册为可执行文件。

为什么要使用 Python Zip 应用程序?

假设您有一个程序,您的团队在其内部工作流程中经常使用该程序。该程序已经从单个文件脚本发展成为具有多个包、模块和文件的成熟应用程序。

此时,一些团队成员难以安装和设置每个新版本。他们不断要求您提供一种更快、更简单的方法来设置和运行程序。在这种情况下,您应该考虑创建一个 Python Zip 应用程序,将您的程序捆绑到一个文件中,并将其作为一个随时可用的应用程序分发给您的同事。

Python Zip 应用程序是发布必须作为单个可执行文件分发的软件的绝佳选择。这也是使用非正式渠道分发软件的便捷方式,例如通过计算机网络发送软件或将其托管在 FTP 服务器上。

Python Zip 应用程序是一种方便快捷的方法,可以将 Python 应用程序打包和分发为即用型格式,可以让您的最终用户的生活更加愉快。

如何构建 Python Zip 应用程序?

正如您已经了解到的,Python Zip 应用程序由一个包含__main__.py模块的标准 ZIP 文件组成,该模块用作应用程序的入口点。当您运行应用程序时,Python 会自动将其容器(ZIP 文件本身)添加到其中,sys.path以便__main__.py可以从塑造应用程序的模块和包中导入对象。

要构建 Python Zip 应用程序,您可以运行以下常规步骤:

  1. 创建包含__main__.py模块的应用程序源目录。
  2. 压缩应用程序的源目录。
  3. 添加一个可选的 Unix shebang 行来定义用于运行应用程序的解释器。
  4. 使应用程序的 ZIP 文件可执行。此步骤仅适用于类 Unix 操作系统。

这些步骤非常简单且可以快速运行。有了它们,如果您拥有所需的工具和知识,就可以在几分钟内手动构建 Python Zip 应用程序。但是,Python标准库为您提供了更方便、更快捷的解决方案。

PEP 441 提议添加一个新模块,称为zipapp标准库。这个模块促进了 Zip 应用程序的创建,它从Python 3.5开始可用。

在本教程中,您将专注于使用zipapp. 但是,您还将学习如何使用不同的工具手动运行整个系列的步骤。这些额外的知识可以帮助您更深入地了解创建 Python Zip 应用程序的整个过程。如果您使用低于 3.5 的 Python 版本,它也会有所帮助。

设置 Python Zip 应用程序

到目前为止,您已经了解了什么是 Python Zip 应用程序、如何构建它们、为什么使用它们以及在创建它们时需要遵循哪些步骤。您已准备好开始构建自己的。不过,首先,您需要有一个可用于 Python Zip 应用程序的功能性应用程序或脚本。

在本教程中,您将使用一个名为 的示例应用程序reader,它是一个最小的Web 订阅源阅读器,可以从Real Python feed读取最新的文章和资源。

接下来,您应该将 的存储库克隆reader到本地计算机中。在您选择的工作目录中打开命令行并运行以下命令:

$ git clone https://github.com/realpython/reader.git

此命令将reader存储库的完整内容下载到reader/当前目录中的文件夹中。

注:查看介绍Git和GitHub上的Python开发者,如果你不熟悉的GitGitHub上

克隆存储库后,您需要安装应用程序的依赖项。首先,您应该创建一个 Python虚拟环境。继续并运行以下命令:

$ cd reader/
$ python3 -m venv ./venv
$ source venv/bin/activate

这些命令在reader/目录中创建并激活一个新的 Python 虚拟环境,该目录是reader项目的根目录。

注意:要在 Windows 上创建和激活虚拟环境,您可以运行以下命令:

C:\> python -m venv venv
C:\> venv\Scripts\activate.bat

如果您在不同的平台上,那么您可能需要查看 Python 关于创建虚拟环境的官方文档。

现在您可以安装reader使用的依赖项pip

(venv) $ python -m pip install feedparser html2text importlib_resources

运行上面的命令将在活动的 Python 虚拟环境中安装所有应用程序的依赖项。

注意:自 Python 3.7 起,importlib_resources在标准库中作为importlib.resources. 因此,如果您使用的是大于或等于 3.7 的版本,则无需安装此库。只需在__init__.py定义reader包的文件中更改相应的导入即可。

下面是一个reader用于从Real Python获取最新文章课程播客集和其他学习资源列表的示例:

(venv) $ python -m reader
The latest tutorials from Real Python (https://realpython.com/)
  0 The Django Template Language: Tags and Filters
  1 Pass by Reference in Python: Best Practices
  2 Using the "and" Boolean Operator in Python
    ...

由于reader在提要中列出了 30 个最新的学习资源,因此此输出对您来说会有所不同。每个学习资源都有一个 ID 号。要从这些学习资源中获取一项的内容,您可以将相应的 ID 号作为命令行参数传递给reader

(venv) $ python -m reader 2
Using the "and" Boolean Operator in Python

Python has three Boolean operators, or **logical operators** : `and`, `or`,
and `not`. You can use them to check if certain conditions are met before
deciding the execution path your programs will follow. In this tutorial,
you'll learn about the `and` operator and how to use it in your code.
    ...

此命令使用Markdown文本格式将文章Using the “and” Boolean Operator in Python 的部分内容打印到屏幕上。您可以通过更改 ID 号来阅读任何可用的内容。

注意:reader工作原理的详细信息与本教程无关。如果您对实现感兴趣,请查看如何将开源 Python 包发布到 PyPI。特别是,您可以阅读名为A Quick Look at the Code 的部分

要从reader存储库创建 Zip 应用程序,您将主要使用该reader/文件夹。该文件夹具有以下结构:

reader/
|
├── config.cfg
├── feed.py
├── __init__.py
├── __main__.py
└── viewer.py

reader/目录中要注意的最重要的事实是它包含一个__main__.py文件。该文件使您能够python -m reader像以前一样使用命令执行包。

拥有__main__.py文件提供了创建 Python Zip 应用程序所需的入口点脚本。在此示例中,__main__.py文件位于reader包内。如果您使用此目录结构创建 Zip 应用程序,则您的应用程序将无法运行,因为__main__.py无法从.zip 文件导入对象reader

要解决此问题,请将reader包复制到名为的外部目录realpython/并将__main__.py文件放在其根目录下。然后删除__pycache__/运行结果的文件夹,python -m reader您之前这样做过。您应该最终得到以下目录结构:

realpython/
│
├── reader/
│   ├── __init__.py
│   ├── config.cfg
│   ├── feed.py
│   └── viewer.py
│
└── __main__.py

有了这个新的目录结构,您就可以使用zipapp. 这就是您将在下一节中执行的操作。

使用以下命令构建 Python Zip 应用程序 zipapp

要创建您的第一个 Python Zip 应用程序,您将使用zipapp. 该模块实现了一个用户友好的命令行界面,该界面为您提供了使用单个命令构建成熟的 Zip 应用程序所需的选项。您还可以zipapp通过模块的Python API从您的代码中使用,该API主要由单个函数组成。

在以下两节中,您将了解使用 .zip 构建 Zip 应用程序的两种方法zipapp

zipapp从命令行使用

的命令行界面zipapp简化了将 Python 应用程序打包成 ZIP 文件的过程。在内部,zipapp通过运行您之前学习的步骤从源代码创建一个 Zip 应用程序。

要从命令行运行zipapp,您应该使用以下命令语法:

$ python -m zipapp <source> [OPTIONS]

如果source是目录,则此命令将从该目录的内容创建一个 Zip 应用程序。如果source是文件,则该文件应该是包含应用程序代码的 ZIP 文件。然后将输入 ZIP 文件的内容复制到目标应用程序存档。

以下是zipapp接受的命令行选项的摘要:

Options Description
-o <output_filename> or --output=<output_filename> 将 Zip 应用程序写入名为output_filename. 此选项使用您提供的输出文件名。如果您不提供此选项,则zipapp使用source带有.pyz扩展名的名称。
-p <interpreter> or --python=<interpreter> 将 shebang 行添加到应用程序的存档中。如果您在POSIX系统上,则zipapp使应用程序的存档可执行。如果您不提供此选项,则您的应用程序存档将不会有 shebang,也将无法执行。
-m <main_function> or --main=<main_function> 生成并写入__main__.py执行main_function. 该main_function参数应具有的形式"package.module:callable"。如果您已经有一个__main__.py模块,则不需要此选项。
-c or --compress source使用Deflate压缩方法压缩内容。默认情况下,zipapp只存储内容source而不压缩它,这可以使您的应用程序运行得更快。

此表提供了zipapp. 有关每个选项的特定行为的更多详细信息,请查看官方文档

现在您已经了解了zipapp从命令行使用的基础知识,是时候构建readerZip 应用程序了。返回终端窗口并运行以下命令:

(venv) $ python -m zipapp realpython/ \
-o realpython.pyz \
-p "/usr/bin/env python3"

在此命令中,您将realpython/目录设置为 Zip 应用程序的源。使用该-o选项,您可以为应用程序的存档提供一个名称realpython.pyz. 最后,该-p选项允许您设置zipapp将用于构建 shebang 行的解释器。

就是这样!现在您将realpython.pyz在当前目录中有一个文件。稍后您将学习如何执行该文件。

为了展示-m和 的--main命令行选项zipapp,假设您决定在将文件移回包的同时更改reader项目布局并重命名__main__.py为。继续创建目录的副本并进行建议的更改。之后,副本应如下所示:cli.pyreaderrealpython/realpython/

realpython_copy/
│
└── reader/
    ├── __init__.py
    ├── cli.py
    ├── config.cfg
    ├── feed.py
    └── viewer.py

目前,您的应用程序的源目录没有__main__.py模块。的-m命令行选项zipapp允许您自动生成它:

$ python -m zipapp realpython_copy/ \
-o realpython.pyz \
-p "/usr/bin/env python3" \
-m "reader.cli:main"

此命令将-m选项 with"reader.cli:main"作为参数。此输入值zipapp表明 Zip 应用程序可调用的入口点main()来自包中的cli.py模块reader

生成的__main__.py文件具有以下内容:

# -*- coding: utf-8 -*-
import reader.cli
reader.cli.main()

__main__.py然后将此文件与您的应用程序源一起打包到一个名为 .zip 的 ZIP 存档中realpython.pyz

使用zipappPython代码

Pythonzipapp还有一个应用程序编程接口 (API),您可以从 Python 代码中使用它。这个 API 主要由一个名为create_archive(). 使用此功能,您可以快速创建 Python Zip 应用程序:

>>>
>>> import zipapp

>>> zipapp.create_archive(
...     source="realpython/",
...     target="realpython.pyz",
...     interpreter="/usr/bin/env python3",
... )

此调用create_archive()采用第一个参数source,该参数表示 Zip 应用程序的来源。第二个参数 ,target保存应用程序存档的文件名。最后,interpreter保存解释器以构建并作为 shebang 行添加到应用程序的 ZIP 存档中。

以下是create_archive()可以采用的参数的摘要:

  • source 可以取以下对象:
    • 现有源目录的基于字符串的路径
    • 路径状物体参照现有的源目录
    • 现有 Zip 应用程序存档的基于字符串的路径
    • 引用现有 Zip 应用程序存档的类似路径的对象
    • 一个类文件对象为读取而打开指向现有的压缩应用程序归档
  • target 接受以下对象:
    • 目标 Zip 应用程序文件的基于字符串的路径
    • 目标 Zip 应用程序文件的类似路径的对象
  • interpreter指定一个 Python 解释器,它在结果应用程序存档的开头写为 shebang 行。省略这个参数会导致没有shebang 行,也没有应用程序的执行权限。
  • main指定zipapp将用作目标存档入口点的可调用文件的名称。main当您没有__main__.py文件时,您提供一个值。
  • filter如果应将源目录中的给定文件添加到最终的 Zip 应用程序文件,则采用布尔值函数应返回True函数
  • compressed 接受一个布尔值,该值决定是否要压缩源文件。

这些参数中的大多数在zipapp. 上面的例子只使用了前三个参数。根据您的特定需求,您也可以使用其他参数。

运行 Python Zip 应用程序

到目前为止,您已经学习了如何使用zipapp命令行和 Python 代码创建 Python Zip 应用程序。现在是时候运行您的realpython.pyz应用程序以确保其正常工作。

如果您使用的是类 Unix 系统,那么您可以通过执行以下命令来运行您的应用程序:

(venv) $ ./realpython.pyz
The latest tutorials from Real Python (https://realpython.com/)
  0 The Django Template Language: Tags and Filters
  1 Pass by Reference in Python: Best Practices
  2 Using the "and" Boolean Operator in Python
    ...

凉爽的!有用!现在您拥有一个可以快速与朋友和同事共享的应用程序文件。

您不再需要调用 Python 来从命令行运行应用程序。由于您的 Zip 应用程序存档在开头有一个 shebang 行,因此操作系统将自动使用您的活动 Python 解释器来运行目标存档的内容。

注意:要运行您的应用程序,您需要在 Python 环境中安装所有必需的依赖项。否则,你会得到一个ImportError.

如果您使用的是 Windows,那么您的 Python 安装应该已经注册.pyz.pyzw文件并且应该能够运行它们:

C:\> .\realpython.pyz
The latest tutorials from Real Python (https://realpython.com/)
  0 The Django Template Language: Tags and Filters
  1 Pass by Reference in Python: Best Practices
  2 Using the "and" Boolean Operator in Python
    ...

reader您在本教程中使用的应用程序有一个命令行界面,因此从命令行或终端窗口运行它是有意义的。但是,如果您有一个 GUI 应用程序,那么您将能够从您最喜欢的文件管理器中运行它,就像您通常运行可执行应用程序一样。

同样,您可以通过使用应用程序的文件名作为参数调用适当的 Python 解释器来执行任何 Zip 应用程序:

$ python3 realpython.pyz
The latest tutorials from Real Python (https://realpython.com/)
  0 The Django Template Language: Tags and Filters
  1 Pass by Reference in Python: Best Practices
  2 Using the "and" Boolean Operator in Python
    ...

在本例中,您使用系统 Python 3.x 安装来运行realpython.pyz. 如果您的系统上有许多 Python 版本,那么您可能需要更具体并使用类似python3.9 realpython.pyz.

请注意,无论您使用什么解释器,都需要安装应用程序的依赖项。否则,您的应用程序将失败。不满意的依赖是 Python Zip 应用程序的常见问题。要解决这种烦人的情况,您可以创建一个独立的应用程序,这是下一节的主题。

创建一个独立的 Python Zip 应用程序 zipapp

您还可以使用zipapp创建自包含或独立的 Python Zip 应用程序。这种类型的应用程序将其所有依赖项捆绑到应用程序的 ZIP 文件中。这样,您的最终用户只需要一个合适的 Python 解释器来运行应用程序。他们不需要担心依赖关系。

要创建独立的 Python Zip 应用程序,首先需要使用pip. 继续并realpython/使用名称创建目录的副本realpython_sa/。然后运行以下命令来安装应用程序的依赖项:

(venv) $ python -m pip install feedparser html2text importlib_resources \
--target realpython_sa/

此命令安装与选项一起reader使用的所有依赖项。的文档说此选项允许您将软件包安装到目标目录中。在此示例中,该目录必须是您的应用程序的源目录.pip install--targetpiprealpython_sa/

注意:如果您的应用程序有requirements.txt文件,那么您可以使用快捷方式安装依赖项。

您可以改为运行以下命令:

(venv) $ python -m pip install \
-r requirements.txt \
--target app_directory/

使用此命令,您可以将应用程序requirements.txt文件中列出的所有依赖项安装到该app_directory/文件夹中。

安装readerinto的依赖项后realpython_sa/,您可以选择删除创建的*.dist-info目录pip。这些目录包含几个带有元数据的文件,pip用于管理相应的包。由于您不再需要该信息,因此可以将其删除。

该过程的最后一步是zipapp像往常一样使用以下命令构建 Zip 应用程序:

(venv) $ python -m zipapp realpython_sa/ \
-p "/usr/bin/env python3" \
-o realpython_sa.pyz \
-c

此命令生成一个独立的 Python Zip 应用程序realpython_sa.pyz。要运行此应用程序,您的最终用户只需要在他们的机器上安装一个合适的 Python 3 解释器。与常规 Zip 应用程序相比,此类应用程序的优势在于您的最终用户无需安装任何依赖项即可运行该应用程序。来试试看吧!

在上面的示例中,您使用 的-c选项zipapp来压缩realpython_sa/. 对于具有许多依赖项且占用大量磁盘空间的应用程序,此选项非常方便。

手动创建 Python Zip 应用程序

正如您已经了解到的那样,zipapp自 Python 3.5 以来,标准库中已经提供了。如果您使用的 Python 版本低于该版本,那么您仍然可以手动构建 Python Zip 应用程序,而无需zipapp.

在以下两节中,您将学习如何使用zipfilePython 标准库创建 Zip 应用程序。您还将学习如何使用一些命令行工具来完成相同的任务。

使用 Python 的 zipfile

您已经拥有realpython/包含reader应用程序源文件的目录。从该目录手动构建 Python Zip 应用程序的下一步是将其存档到 ZIP 文件中。为此,您可以使用zipfile. 该模块提供了方便的工具来创建、读取、写入、附加和列出 ZIP 文件的内容。

下面的代码显示了如何reader使用zipfile.ZipFile和其他一些工具创建Zip 应用程序。例如,代码依赖pathlibstat读取源目录的内容并为结果文件设置执行权限:

# build_app.py

import pathlib
import stat
import zipfile

app_source = pathlib.Path("realpython/")
app_filename = pathlib.Path("realpython.pyz")

with open(app_filename, "wb") as app_file:
    # 1. Prepend a shebang line
    shebang_line = b"#!/usr/bin/env python3\n"
    app_file.write(shebang_line)

    # 2. Zip the app's source
    with zipfile.ZipFile(app_file, "w") as zip_app:
        for file in app_source.rglob("*"):
            member_file = file.relative_to(app_source)
            zip_app.write(file, member_file)

# 3. Make the app executable (POSIX systems only)
current_mode = app_filename.stat().st_mode
exec_mode = stat.S_IEXEC
app_filename.chmod(current_mode | exec_mode)

此代码运行三个必需的步骤,最终得到一个成熟的 Python Zip 应用程序。第一步向应用程序的文件中添加一个shebang 行。它open()with语句中使用创建文件对象 ( app_file) 来处理应用程序。然后它调用.write()app_file.

注意:如果你在 Windows 上,你应该用UTF-8编码 shebang 行。如果您使用的是POSIX系统,例如 Linux 和 macOS,您应该使用sys.getfilesystemencoding()返回的任何文件系统编码对其进行编码。

第二步使用ZipFile嵌套with语句压缩应用程序的源目录内容。该for循环遍历文件中realpython/使用pathlib.Path.rglob()并将它们写入zip_app。请注意,.rglob()通过目标文件夹递归搜索文件和目录app_source

member_file最终 ZIP 存档中每个文件的文件名realpython/. 这就是您pathlib.Path.relative_to()在上面的示例中使用的原因。

最后,第三步使用pathlib.Path.chmod(). 为此,您首先使用文件的当前模式,pathlib.Path.stat()然后将此模式与按位OR 运算符 ( )结合stat.S_IEXEC使用。请注意,此步骤仅对 POSIX 系统有效。|

运行这些步骤后,您的realpython.pyz应用程序就可以运行了。继续并从命令行尝试一下。

使用 Unix 命令行工具

如果您使用的是类 Unix 系统,例如 Linux 和 macOS,那么您还可以使用命令行中的特定工具运行上一节中的三个步骤。例如,您可以使用以下zip命令压缩应用程序源目录的内容:

$ cd realpython/
$ zip -r ../realpython.zip *

在本例中,您首先cd进入realpython/目录。然后使用带有选项的命令将 的内容压缩realpython/到。此选项递归遍历目标目录。realpython.zipzip-r

注意:另一种选择是zipfile从命令行使用 Python 。

为此,请从realpython/目录外部运行以下命令:

$ python -m zipfile --create realpython.zip realpython/*

--create命令行选项zipfile允许您从源目录创建 ZIP 文件。*附加到realpython/目录的星号 ( )告诉将该目录zipfile的内容放在生成的 ZIP 文件的根目录中。

下一步是在 ZIP 文件中添加一条 shebang 行realpython.zip,并将其另存为realpython.pyz. 为此,您可以在管道中使用echocat命令:

$ cd ..
$ echo '#!/usr/bin/env python3' | cat - realpython.zip > realpython.pyz

cd ..命令让您退出realpython/. 的echo命令发送'#!/usr/bin/env python3'到标准输出。管道符 ( |) 将标准输出的内容传递给cat命令。然后cat将标准输出 ( -) 与 的内容连接起来realpython.zip。最后,大于号 ( >) 将cat输出重定向到realpython.pyz文件。

最后,您可能希望使用以下chmod命令使应用程序的文件可执行:

$ chmod +x realpython.pyz

在这里,chmod将执行权限 ( +x)添加到realpython.pyz. 现在您已准备好再次运行您的应用程序,您可以像往常一样从命令行执行此操作。

使用第三方工具创建 Python 应用程序

在 Python 生态系统中,您会发现一些与zipapp. 它们提供了更多功能,可以用于探索。在本节中,您将了解其中两个第三方库:pexshiv.

pex项目提供了一个创建 PEX 文件的工具。PEX 代表Python 可执行文件,是一种存储独立的可执行 Python 虚拟环境的文件格式。该pex工具将这些环境打包成带有 shebang 行和__main__.py模块的ZIP 文件,允许您直接执行生成的 PEX 文件。该pex工具是对 PEP 441 中概述的想法的扩展。

要使用 来创建可执行应用程序pex,您首先需要安装它:

(venv) $ python -m pip install pex
(venv) $ pex --help
pex [-o OUTPUT.PEX] [options] [-- arg1 arg2 ...]

pex builds a PEX (Python Executable) file based on the given specifications:
sources, requirements, their dependencies and other options.
Command-line options can be provided in one or more files by prefixing the
filenames with an @ symbol. These files must contain one argument per line.
    ...

pex工具提供了一组丰富的选项,可让您微调 PEX 文件。以下命令显示了如何为reader项目创建 PEX 文件:

(venv) $ pex realpython-reader -c realpython -o realpython.pex

此命令realpython.pex在您的当前目录中创建。这个文件是一个 Python 可执行文件,用于reader. 请注意,它pex处理PyPI的安装reader及其所有依赖。该reader项目在 PyPI 上可用,名称为realpython-reader,这就是为什么您使用该名称作为pex.

-c选项允许您定义应用程序将使用哪个控制台脚本。在这种情况下,控制台脚本realpython中定义setup.py的文件reader。该-o选项指定输出文件。像往常一样,您可以./realpython.pex从命令行执行以运行应用程序。

由于内容.pex文件被执行之前解压缩,PEX应用程序解决的限制zipapp应用程序,并允许您从执行代码.pyd.so.dll文件。

最后要注意的细节是pex在生成的 PEX 文件中创建和打包 Python 虚拟环境。这种行为使您的 Zip 应用程序比使用zipapp.

您将在本节中学习的第二个工具是shiv. 它是在PEP 441描述构建自成体系的Python邮编应用程序的命令行实用程序的优点shiv相比,zipappshiv会自动包括所有在最后归档应用程序的依赖关系,使他们在Python的可用模块搜索路径

要使用shiv,您需要从 PyPI 安装它:

(venv) $ python -m pip install shiv
(venv) $ shiv --help
Usage: shiv [OPTIONS] [PIP_ARGS]...

  Shiv is a command line utility for building fully self-contained Python
  zipapps as outlined in PEP 441, but with all their dependencies included!
    ...

--help选项显示完整的使用消息,您可以查看该消息以快速了解shiv工作原理。

要使用 构建 Python Zip 应用程序shiv,您需要一个带有setup.pypyproject.toml文件的可安装 Python 应用程序。幸运的是,reader来自 GitHub的原始项目满足了这个要求。返回包含克隆reader/文件夹的目录并运行以下命令:

(venv) $ shiv -c realpython \
-o realpython.pyz reader/ \
-p "/usr/bin/env python3"

与该pex工具一样,shiv可以-c选择为应用程序定义控制台脚本。在-o-p选项允许你提供一个输出文件名和适当的Python解释器,分别。

注意:上面的命令按预期工作。但是,shiv(0.5.2)的当前版本会pip显示关于它如何构建包的弃用消息。由于直接shiv 接受pip参数,您可以放置--use-feature=in-tree-build在命令的末尾,以便安全shiv使用pip

不像zipappshiv使您可以使用.pyd.so以及.dll文件在应用程序的归档存储。为此,shiv在存档中包含一个特殊的引导功能。此函数将应用程序的依赖项解压到.shiv/您的主文件夹中的一个目录中,并将它们添加到 Python 的sys.path.

此功能允许您创建独立的应用程序,其中包含部分用 C 和 C++ 编写的库以提高速度和效率,例如NumPy

结论

拥有一种快速有效的方式来分发您的 Python 可执行应用程序可以在满足最终用户的需求方面发挥重要作用。Python Zip 应用程序为您提供了一种有效且易于访问的解决方案,用于捆绑和分发可立即运行的应用程序。您可以使用zipappPython 标准库快速创建您自己的可执行 Zip 应用程序并将它们传递给您的最终用户。

在本教程中,您学习了:

  • 什么是Python的应用邮编
  • Zip 应用程序如何在内部工作
  • 如何构建您自己的 Python Zip 应用程序 zipapp
  • 什么是独立的 Zip 应用程序以及如何使用pip和创建它们zipapp
  • 如何使用命令行工具手动创建 Python Zip 应用程序

有了这些知识,您就可以快速创建 Python Zip 应用程序,作为将 Python 程序和脚本分发给最终用户的便捷方式。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。