简单梳理当前 Python 依赖管理和构建工具生态

如果你从前只接触过 C/C++ 或是 Java,可能对 Python 自带的这个 pip 非常满意——$ pip install <package_name> 可以一键从 PyPI (Python Package Index) 安装 Python 包。

但是一旦开始正经开发项目,你就意识到 pip 是个很蠢的东西——它总是把依赖安装到全局环境里,从不给你做隔离和版本管理,一旦遇到两个项目之间的包发生冲突就直接抓瞎,毕竟你一个全局环境里显然只能安装一个版本的包。

一种常见的做法是用 $ python -m venv venv 创建虚拟环境,然后 $ ./venv/Scripts/activate 进入虚拟环境,再操作 pippython,然后在虚拟环境中认真管理你的依赖,确保只包含必要的依赖,并使用 $ pip freeze > requirements.txt 将它们导出——或者用 pipreqs,这可能是生成 requirement.txt 更好的方案。这显然相对麻烦,而且 requirements.txt 没办法区分 pytest 或 Black 这样的开发期依赖,它们会一股脑被放到里边。另外如果你需要构建自己的库发布到 PyPI 上,你还需要自己写 setuptools 的 setup.py 做打包,然后手动写一堆脚本发布到 PyPI 上(经 @银河-蜗牛 指正,setuptools 目前也对 pyproject.toml 提供了良好的支持,可以被认为是一个可靠与合适的选择)。

或许你最近听说过,Poetry 是个更现代化的工具,自动创建并使用虚拟环境,并且集成了依赖管理、构建和发布到 PyPI——如果你只有开发普通纯 Python 应用程序的需求,不用往下看了,用 Poetry 肯定是你最好的选择。

但如果你想更多了解 Python 在依赖管理和包管理生态上的感(逆)人(天)现状,可以接下去看看 Python 社区目前到底为这档子事折腾了多少幺蛾子。

Poetry, Hatch 和 PDM

目前最流行与功能相对完整的依赖管理与构建工具有三个,PoetryHatchPDM. 不过在近期的数据中,Poetry 在这三者中的优势仍比较明显(感谢 @银河-蜗牛 对数据的更新与指正):

这就是为什么我推荐如果你在构建一个纯 Python 应用,优先选择 Poetry——它显然具有更好的生态和流行度,资料也更容易找。

上面列出的各种工具有点多,让我们先关注这里提到的三个工具。它们都集成了依赖管理(使用 PEP-621 规定的 pyproject.toml 管理项目元数据)、打包构建和发布到 PyPI 的能力。

  • Poetry 最流行,历史最悠久,并且文档也很不错。它的缺点是只能构建纯 Python 项目,如果你的项目里有 C 或 C++ 扩展会比较折腾。此外 Poetry 并不完全遵循 Python 的相关标准,尤其是至今还不兼容 PEP-621 中的标准——这可能是由于 Poetry 官方觉着 PEP-621 提供的能力还不如 Poetry 自己能提供的多,所以不太想兼容它。
  • PDM 是最新的选择,支持自定义构建后端(也就是说与 C/C++ 扩展等的集成不错),并且遵循 PEP-621 等标准。相比之下,PDM 安装包的速度也比 Poetry 快不少。同时 PDM 也是个维护非常积极的项目,目前解决 BUG 的速度很快。当然,在成熟度上肯定不如 Poetry.
  • Hatch——原谅我没用过 Hatch,主要是由于它因为 Python 还未标准化 lockfile 而选择干脆不支持它。Hatch 最炫酷的特性在于它有个 Environment Matrix 的概念,可以同时管理多个使用不同 Python 版本的隔离虚拟环境。另外 Hatch 对自定义 Script 的处理更接近 npm 那一套,而不是像 Poetry 一样指向一个具体的 Python 函数。另外 Hatch 是这三者唯一目前进入 PyPA (Python Packaging Authority) 的,可能更加“官方”一点——说实话也官方不到哪里去,毕竟它只能算是被“招安”的,实际上目前也算不上是官方在维护它,还是原团队在做。

另外,Rye 是 Flask 作者最近开发的一个实验性包管理器,与这三者有些不同,它更多是对 pip、pip-tools 等工具的集成,旨在更好解决 Python 在此方面极其混乱的生态——我不知道这会不会导致 Python 在这方面的生态更加混乱,导致流行的相关工具从三个变成四个……只能说目前来说它看上去像个有价值的尝试。

呃,所以说你问我该选哪个?能用 Poetry 还是推荐用 Poetry,尽管它有些不那么遵循标准,但它的流行度基本上可以让你用脚投票。但如果你打算发布一个库,并且希望更遵循 Python 标准,我可能会更推荐 PDM,它比较活跃一些,对自定义构建后端的支持也不错。

数据科学与人工智能

如果你经常用 Python 写数据科学和人工智能相关的代码,大概对我这里提到的一切都非常陌生。在该领域,Conda、Mamba、scikit-build 等是更流行的选择。

它们并不是什么坏选择。Conda-build 在此方面表现良好,并且能够很好与非 Python 环境集成——Conda 本身就是一个“适用于任何语言的打包、依赖和环境管理工具”,只是它在 Python 的应用最多而已。

只是本文并不太多探讨这方面的应用,它们更多被认为属于数据科学技术栈而非 Python 应用开发技术栈。

构建后端与构建前端

该小节一定程度上参考自这里

这里的前后端和 Web 的前后端一点关系都没有——就像编译器的前后端也和 Web 前后端没一点关系,这点我首先要声明一下。

Python 包的构建实际上比大部分人认知的要复杂很多——包的分发实际上分为 sdist 和 wheel 两部分,前者是用来编译的源代码,而后者是针对各个不同目标平台(包括不同 Python 版本和不同操作系统、CPU 指令集架构等)编译的结果。这很大程度上源于 Python 生态和 C/C++ 扩展的紧密绑定,许多包都需要针对不同平台进行编译,以至于 PyPA 里都有两个项目 cibuildwheelmanylinux 专门处理针对不同平台构建 wheel 的问题。

这其实很不理想——你可能时不时就碰到用 Python 安装某个包时提示你构建失败的问题。如果某个包在你的平台上未提供对应的 wheel,pip 就会直接从 sdist 开始当场编译,由于 C/C++ 编译系统的复杂性,这一步很容易失败。

Python 标准中至今都没有被通过的 PEP 提案来规范如何以二进制形式分发 Python 包,这也是上面提到的 Rye 以及 pip-tools 这样的工具出现的一大原因。

这个构建的步骤就是构建后端的工作——生成 sdist 并编译出各种目标平台的 wheel. Poetry 使用的构建后端只能是它自己的 poetry-core,Hatch 也主要使用自己的 Hatchling,PDM 默认使用 PDM-Backend,但对其他构建后端有良好的兼容性,可以比较轻松地换成 setuptools、Flit、Hatchling、Maturin 等。

另外,经 @银河-蜗牛 指出,setuptools 目前也是良好与标准化的选择。setuptools 有文档提供了相关教程,指导你如何使用 setuptools + python -m build + Twine 使用现代化方式构建和在 PyPI 上发布包。

构建前端就是像 Poetry、PDM 这样的管理工具,提供了更现代化和简单的构建方式(包括上面提到的调用构建后端生成构建产物)、安装和管理依赖、发布到 PyPI、与测试工具集成等。

其他工具

我在上面并未提到 Pipenv——这在过去是一个非常流行的工具,但目前对比起几个现代化依赖管理和构建工具来说它可以说比较失败,用起来也远没有它们方便。Pipenv 专注的功能比较简单,如它名称暗示的,它结合了 pip 和 venv,适合用于给 Python 应用创建和管理虚拟环境中的依赖,并且会生成一个 Pipfile.lock 作为 lockfile,也支持从 Pipfile.lock 生成 requirements.txt——在许多年前算是最好的解决方案,但如今早就不是了,你明显也可以看出来它提供的功能远没有 Poetry 这样的工具丰富,连自己的构建后端都没有(需要自己用 setuptools、Flit 等再配一遍),也没提供发布到 PyPI 的功能。

pip-tools 如它名称暗示的,它只是个扩展 pip 的工具。它本身甚至没自动帮你把管理虚拟环境做了,你得手动创建虚拟环境然后在里边安装 pip-tools. 你需要首先在 pyproject.toml 里手写好依赖,然后用 pip-tools 提供的 pip-compile 命令编译出一个 requirements.txt,它也支持各种其他格式如 setup.pyrequirements.in 等(这个 requirements.txt 其实充当了 lockfile,它并不完全等价于我们通常用 pip 导出的那个)。在有了 requirements.txt 后,你可以使用 pip-sync 命令将其内容与当前虚拟环境同步,它会自动安装相应的依赖(也会自动移除其中没有的依赖) 。pip-tools 通过两个命令实现了简洁和鲁棒的依赖管理,也足够现代化,如果你喜欢开手动挡的话应该会觉得不错——但肯定没有 Poetry 这种工具开箱即用,用 pip-tools 你肯定要手写不少脚本来自动化工作流程。

Flit 是个简单和纯粹的构建后端,它只负责把不包含任何额外构建步骤的简单 Python 库打包并发布到 PyPI 上——它不负责管理依赖,你得手动写到 pyproject.toml 里。如果你只使用 Flit,你的包也不能包含任何额外的构建步骤,得是个没 C/C++ 扩展也不捆绑 JS 之类东西的纯 Python 包——其实 PyPI 上的大多数包都是这样的,因此其实挺适合用 Flit 构建的。

Twine 是个更纯粹的工具,只负责把构建好的 dist 发布到 PyPI 上。如果你用 setuptools 之类的方式构建包,加个 Twine 就比较合适。

实际上,除开这些社区生态,Python 本身也具有足够标准的构建和发布流程,但是相对复杂,没有 Poetry 等工具容易配置,即使用 setuptools + python -m build + Twine 进行构建与发布,在此基础上你可以使用 pip + venv + pip-tools 管理依赖。

当然,还有很多其他工具我未能全部介绍。另外将 Python 项目打包到单独的二进制文件有关的项目我并未包含在这里,比如 PyOxidizerPyInstallershiv 等。

以上就是“简单梳理当前 Python 依赖管理和构建工具生态”的全部内容,希望对你有所帮助。

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

二、Python必备开发工具

img

三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

五、Python练习题

检查学习结果。

img

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

img

最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值