为了账号安全,请及时绑定邮箱和手机立即绑定

Python打包最佳实践

最好的分享你的Python项目并让他人安装的方式是将其打包并分发。

例如,为了让其他开发人员共享一个库,让他们在自己的应用程序中使用,或者像‘py.test’这样的开发工具。

这种方法的一个优势是它有一个成熟的工具生态系统,比如 PyPIpip ,这些工具使得其他开发人员可以轻松地下载和安装您的 Python 包,无论是为了简单的实验还是大型专业系统。

Python 包构建流程。从源代码到 Python 包,再到公共包仓库,最后用 pip 安装包。

包装 在这一上下文中指的是两件事:构建并分发一个软件包。

包装就是打包加上分发

在这篇文章中,我将谈谈构建Python包的最佳方法。

免责声明:以下内容适用于您编写简单的包,例如纯Python包。如果您有一个更复杂的Python包需求,则仍然应使用基于pyproject.toml的构建,并按照指示设置项目元数据。不过,在选择构建后端时,您可能还需考虑其他因素。

不过,让我们从头开始吧……

Python库到底是什么呢?

Python包是一些按特定格式打包的Python代码(通常是以压缩文件的形式),可以分享给他人并通过工具如pip进行安装。

现在基本上有两种类型的Python包在使用

  • 源代码包(.tar.gz):包含源代码的快照以及一个包含名称、版本、简介、作者等元数据的清单文件。
  • Wheel 包(.whl):基于 Egg 格式改进,现在是最受推荐的格式。

2种Python库。

现在的问题在于,我们如何将源代码打包成一个可以分发的Python包?继续阅读以了解如何打包我们的代码(以及最好的方法)。

构建标准

当你想构建一个 Python 包时,最常想到的词是 setup.pysetup.cfgsetuptools ,……对吧?嗯,这些就是所谓的“旧标准”(如您可以在 Python 文档中看到,这里),使用这些工具打包已经有些过时了。

传统的打包标准适用于Python打包。

那么……让我们热烈欢迎使用pyproject.toml的打包方式吧!

“新的打包标准”用于Python打包。

使用旧标准构建以及你最好避免这样做

为何避免使用旧标准构建

以前,你使用一个第三方工具(通常是 setuptools)并使用文件 setup.pysetup.cfg 来构建你的包(这基本上对应于如图所示的蓝色部分)。

“老旧建筑图”。

这事儿就像执行以下命令这么简单:

其中 sdist 代表源代码分发,而 bdist_wheel 简单说就是用 wheel 格式打包的二进制文件,。

到这一步,是不是感觉挺简单的?但等等……旧的建筑程序主要有什么问题,这里我们主要说两个问题。

记得,老的打包方式是通过一个 setup.py 文件来完成的。你得写一个函数调用,该函数是从 setuptools 包中导入的 setup 函数,并定义你包的所有元数据。

首先,这是非结构化数据!你需要运行这个setup.py Python 脚本才能读取这些数据,因为数据的读取方式需要通过代码来指定。它比实际需要的更复杂,而且没有很多防止不当操作的指导。由于这是一个脚本,人们可以随心所欲地编写代码做各种事情

处理setup.py文件时的另一个问题是解决构建依赖项。

考虑以下情况:假设你有一个包,它需要使用 PyTorch 来构建,并且需要 C++ 和 CUDA 扩展。你将在你的 setup.py 中导入来自 torch 的内容。这意味着你必须在你的环境中先安装 torch,然后才能通过 pip install 从源代码安装该包。更糟糕的是,仅仅在依赖项中列出 torch 是不够的。即使在 requirements.txt 文件中同时列出 torch 和你的包也不够。pip 甚至无法检查该包的依赖项:pip 需要运行 setup.py 来获取依赖项,但 setup.py 无法运行,因为它需要导入 torch。为什么你需要安装依赖项并运行代码来读取一堆静态元数据?为什么安装一个 Python 包需要这么多步骤?此外,如果你只需要某些依赖项来构建,而不需要这些依赖项在运行时存在,让用户安装并保留这些依赖项在他们的环境中会让他们感到很烦恼。

鉴于这些和其他原因,你应该按照新的标准来构建你的Python库。

用新标准来构建

“新标准规范”指的是在pyproject.toml文件中标准化指定包的元数据(如包名、作者、依赖项),并使用这些元数据通过源代码进行包的构建(称为构建后端)。人们通常称其为“基于pyproject.toml的构建”。

新标准的两个部分。

这两个组件基于两个主要的PEP(Python Enhancement Proposals),这些PEP实际上是关于Python中新的标准或功能的设计文件。它们是 PEP 517PEP 621

Python项目的《Pyproject.toml》配置文件和《PEP 621》建议规范

pyproject.toml 文件是用于配置打包工具以及其他工具的,它包括包名、作者、依赖项等包元数据。

pyproject.toml 文件是用 TOML 编写的。目前定义了三个表(TOML 中表示部分的方式),分别是如下:[build-system][project][tool]。其他表则保留以备将来使用(特定工具的配置应该放在 [tool] 表下)。

PEP 621 定义了 [project] 应该包含的内容标准。

pyproject.toml文件示例

关于后端和 PEP 517

你可能在想:后端具体是指什么呢?

后端是读取你的 pyproject.toml 并实际将你的源代码转换成可安装和分发的包存档的程序。前端只是一个用户界面(通常是一个命令行工具),它调用后端程序。

  • 前端工具示例如下:pip, build, poetry, hatch, pdm, flit
  • 后端工具示例如下:setuptools(版本61及以上),poetry-core, hatchling, pdm-backend, flit-core

将这两部分在构建过程中分开设计意味着你可以自由组合前后端。但这留待下次再谈 :-)

要使用特定的构建后端,只需在你的 pyproject.toml 中包含如下所示的“build-system ”部分,如下配置:

在你的 pyproject.toml 文件中配置后端。

在上面的例子中,flit 作为后端被使用。查阅你所选后端的文档,了解如何在 pyproject.toml 文件中配置它。下面是一些后端示例及其在 pyproject.toml 文件中的配置方式。

这里有一些后端示例。

PEP 517规定了其他内容,其中包括必须实现的钩子(例如build_wheelbuild_sdist)。这些钩子。这基本上就是后端需要实现的接口。

PEP 517定义了build_wheel接口,这里给出一个示例。

所以,遵循PEP 517规范的后端通常称为“符合PEP 517的后端”。

现在要问的是:我该选哪个构建工具?

如果你正在编写一个简单的纯 Python 包程序,使用任何符合 PEP 517([build-system])和 PEP 621([project])的后端,你得到的结果都会大致相同。

不过,在我看来,有两个主要考虑可以帮您决定选哪个后端:

  1. 与构建过程相关的额外特性,例如自定义构建包中包含哪些额外文件,在构建过程中运行代码,以及如何处理动态字段。最常见的动态字段是包版本;许多后端支持从源代码或仓库的版本控制系统中读取该版本号。如果你需要这些特性,那么你需要一个支持这些特性的构建后端。然后,你可以这样在你的 pyproject.toml 文件中指定,以指示 hatchling 后端包含或排除文件:

雏鸟孵化中的额外功能示例

  1. 与前端系统的整合,提供额外的项目和工作流管理功能。这些后端系统通常紧密集成到强大的工作流管理系统中。例如 poetry/poetry-core, hatch/hatchling, pdm/pdm-backend。实际上,这些前端工具不仅作为构建过程的前端存在,还提供了许多其他功能。它们是Python项目的全面工作流管理工具,例如,包括功能特性如:
  • 创建和管理您的虚拟环境。

  • 管理与安装您的依赖项的命令。

  • 依赖锁定文件(lockfiles)

  • 上传您的软件包到PyPI的命令行。

下面你看到的是一个使用PDM作为后端的完整pyproject.toml文件的例子。

一个使用PDM作为后端的pyproject.toml文件的例子。

正如你所见:

  • 该项目符合 PEP 621(例如 [project] 部分)。
  • 后端是 PDM,这是 PEP 517 后端(例如 [build-system] 部分)。
  • 包含特定的构建功能(例如 [tool.pdm.*] 部分)。
摘要

如果你想使用常用的现代打包标准创建一个Python包

  1. 在您的 pyproject.toml 文件的 [build-system] 表中指定构建后端。
  2. 在您的 pyproject.toml 文件的 [project] 表中指定项目的元数据。

选择要使用的后端服务:

  • 如果你的项目比较简单,选择任何支持 PEP 517 和 PEP 621 的后端都可以。目前流行的选项包括 flit-core、hatchling、pdm-backend 和 setuptools (>=61)。到目前为止,Poetry 符合 PEP 517 标准但尚未符合 PEP 621 标准。
  • 如果你的项目需要更复杂的构建功能,比较每个工具在 pyproject.toml 文件中的 [tool.*] 部分所配置的特定构建功能。
  • 如果你希望使用一个功能全面的工作流程工具,可以管理诸如虚拟环境和依赖项等其他相关事项,比较这些工具在这方面的功能。Poetry、Hatch 和 PDM 目前都很受欢迎,尽管 Poetry 还没有完全符合所有标准。

我个人喜欢PDM,原因多样。它同时符合PEP 517和PEP 621的要求,并具备良好的构建特性,还具备一个强大的前端界面,提供多种工作流程管理选项。PDM(Project Delivery Method,项目交付方法)。

希望这能帮助你更清楚地了解Python中当前的打包标准,祝你打包愉快! :-)

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消