写点什么

从混沌到秩序:Python 的依赖管理工具分析

  • 2024-12-20
    福建
  • 本文字数:3350 字

    阅读完需:约 11 分钟

Python 的依赖管理工具一直没有标准化,原因主要包括:


  1. 历史发展的随意性Python发展早期对于依赖管理的重视程度不足,缺乏从一开始就进行统一规划和设计的意识

  2. 社区的分散性Python社区庞大且分散,众多开发者和团队各自为政,根据自己的需求和偏好开发工具,缺乏统一的协调和整合机制

  3. 多样化的使用场景Python应用场景广泛,从 Web 开发到数据科学、机器学习、系统管理脚本等。不同场景对依赖管理有着不同的要求

  4. 向后兼容性的挑战Python 语言本身非常注重向后兼容性,这在一定程度上限制了对依赖管理工具进行根本性变革的可能性

  5. 缺乏统一的治理:与一些编程语言(如 Java 有 Oracle 主导的规范制定)不同,Python 没有一个强有力的单一实体来主导依赖管理工具的标准化工作

  6. 生态系统的快速变化Python 生态系统发展迅速,新的库和框架不断涌现,这使得依赖关系变得越来越复杂


1. 什么是依赖管理


依赖管理工具常用于处理软件项目中的依赖关系。


在软件开发过程中,一个项目往往会依赖于许多其他的软件库、框架或组件。


依赖管理工具能够帮助开发者精确地指定这些依赖项的版本,自动下载和安装它们,并且可以在不同的环境中(如开发、测试、生产环境)保证依赖项的一致性。


这样可以有效避免因依赖版本混乱而导致的软件故障、兼容性问题等情况。


比如,其他编程语言的标准依赖管理工具有:NodeJSnpmRustcargoJavaMaven等等。


依赖管理工具最关键的作用是可重复性,意味着我们可以遵循一系列步骤,最终得到的软件项目是完全相同的。


特别是现在的项目(不管是开源的还是内部的)基本都需要多人协作,确保每个人的代码编译出来的软件运行结果一致是至关重要的。


良好的依赖管理可以对开发构建部署阶段的所有依赖关系都明确声明,并与版本控制中的代码一起跟踪。


简单来说:应用程序=代码+所有依赖项


具体可以归纳为以下几个步骤:


  1. 创建定义文件:项目的描述,声明所需的依赖项和最小版本约束等

  2. 生成锁定文件:固定依赖项的版本和依赖项之间的关系

  3. 同步环境:一般都过 git 之类的版本管理工具互相同步

  4. 追踪定义文件和锁定文件:定义文件和锁定文件有变化时及时互相同步


2. 依赖管理工具对比


Python 的依赖管理工具虽然没有统一,但是有很多可供选择,下面一一分析每个工具的优缺点。


2.1. pip


pip是自带的默认包管理器,也是使用最多的工具,它的特点是只能用来安装Python包。


优势

  1. Python 3.4起包含在Python中,无需额外安装

  2. 2013 年开始引入wheels分发格式,安装速度大大提高

  3. 2020 年开始加入了依赖解析算法,能够更好的保持环境的一致性


不足之处

  1. 依赖Python,也就是说使用pip必须先安装Python

  2. 不能安装非 Python 的包

  3. 没有锁定文件


2.2. venv


用于创建虚拟环境的内置工具,在虚拟环境中可使用 pip 安装包,通过设置环境变量来隔离环境。


优势:自Python 3.3起包含在Python中。


不足之处

  1. 是 Python 工具,依赖 Python 安装

  2. 所有环境必须使用相同的 Python 解释器

  3. 无法安装非 Python 包


2.3. virtualenv


在 venv 成为 Python 内置工具前,我们通常使用virtualenv创建虚拟环境,可指定不同的 Python 解释器创建虚拟环境,需通过 pip 安装。


优势:能指定不同 Python 解释器创建虚拟环境。


不足之处venv 是一样的。


2.4. pip-tools


轻量级工具,引入锁文件机制。


需先编写requirements.in作为定义文件,再用pip-compile生成requirements.txt锁文件,同步环境是使用pip-sync


优势:轻量、简单,与基本的 <font style="color:rgba(0, 0, 0, 0.85);">pip/venv</font> 工具协同工作。


不足之处

  1. 是 Python 工具,需安装到项目环境中,可能存在兼容性问题

  2. 只能处理 pip 可安装的包

  3. 定义文件需手动维护


2.5. Pipenv


整合了 pipvirtualenv 和 pip-tools 的功能,通过PipfilePipfile.lock管理依赖和虚拟环境,自动更新文件。


优势:轻量、简单,包装了基本的 pip/venv 工具。


不足之处

  1. 是 Python 工具

  2. 有自己的定义和锁文件格式

  3. 只能处理 pip 可安装的包

  4. 只能区分开发和非开发依赖,环境定义不够灵活


2.6. Poetry


旨在涵盖 Python 项目整个开发流程,包括项目引导、虚拟环境、依赖管理、构建和发布包。

通过pyproject.toml管理依赖,自动维护poetry.lock,支持依赖分组。


优势

  1. 一体化工具,涵盖项目开发全生命周期

  2. 有方便的命令行界面

  3. 支持依赖分组


不足之处

  1. 是 Python 工具,较重量级,依赖多,安装可能有问题

  2. 与其他工具互操作性差,不支持其他构建后端

  3. 不支持维护互斥环境

  4. 有自己的依赖定义和锁文件格式

  5. 只能处理 pip 可安装的包


2.7. PDM


类似于 Poetry,但遵循 PEP 标准,可使用uv进行依赖解析和安装,其构建后端可独立使用。

uv是后面将要介绍的另一个依赖管理工具。


优势

  1. 遵循 PEP 标准

  2. 可利用uv进行依赖管理


不足之处:与 Poetry 类似,是 Python 工具,有较多依赖,存在相关缺点。


2.8. pyenv


用于安装和管理不同版本的 Python,可在全局或项目级别激活指定版本,是简单的 shell 实用程序,不依赖 Python 安装。


优势

  1. 纯 shell 脚本,无 Python 依赖

  2. 遵循 Unix 哲学,专注于管理 Python 版本


不足之处

  1. 安装新 Python 版本需下载并编译源代码,耗时

  2. 首次设置可能较麻烦,需安装多个构建依赖

  3. 不支持 Windows


2.9. pipx


将 pip 包安装在用户级别的独立虚拟环境中,避免依赖冲突,通过 symlink(软链接) 将入口点链接到PATH,方便调用。


优势:比直接在用户级别 pip 安装工具更好,能隔离依赖,可使用不同 Python 解释器。


不足之处

  1. 是 Python 工具

  2. 无法安装同一工具的多个版本,所有项目需共享工具版本


2.10. uv


用 Rust 编写的全能工具,旨在替代多个 Python 管理工具,处理整个开发流程,包括安装包、管理虚拟环境、构建和发布等。


遵循 Python 标准,依赖定义在pyproject.toml,锁文件为uv.lock,支持任意依赖分组,能安装 pip 包作为可执行文件,可管理 Python 版本,维护全局包缓存。


优势

  1. 用 Rust 编写,速度极快,单二进制文件,无外部依赖

  2. 多平台支持

  3. 一体化工具,功能全面

  4. 遵循 Python 标准

  5. 支持选择任何构建后端

  6. 支持依赖分组。


不足之处

  1. 不支持维护多个互斥环境

  2. 只能处理 pip 可安装的包


2.11. Conda


由 Anaconda 公司开发的不同生态系统的包管理器,主要用于安装anaconda.org上的包,

能创建虚拟环境,与 pip 生态系统不同,对【】 的定义更广泛,包括共享库、头文件、可执行文件等。


优势

  1. 多平台支持

  2. 有全局包缓存

  3. 包以编译二进制形式分发

  4. 依赖解析算法健壮

  5. 可在 Conda 环境中使用 pip

  6. 支持全局和共享环境


不足之处

  1. 速度慢

  2. 包的下载是串行的

  3. 安装过程有些侵入性,会修改shell配置

  4. 与 “” Python 生态系统互操作性有限

  5. 无锁文件

  6. 构建和分发 Conda 包较痛苦


2.12. Mamba


Conda的改进版,旨在解决Conda的痛点,如慢的依赖解析和并行下载问题,用 C++ 实现,使用不同算法,推荐安装方式已改变。


速度比Conda 快很多,其他方面和Conda类似。


2.13. Pixi


类似于 uv,但针对 Conda 生态系统,用 Rust 编写,支持多平台。


通过pyproject.tomlpixi.toml配置,有方便的命令行界面,支持管理多个虚拟环境和定义文件,有锁文件机制,支持类似 Makefile 的项目自动化任务,可指定系统依赖,但不帮助构建包。


优势

  1. 用 Rust 编写,速度快,单二进制文件,无外部依赖

  2. 多平台支持

  3. 方便的命令行界面

  4. 全局包缓存

  5. 可下载 Python 二进制文件和anaconda.org上的非 Python 包

  6. 能使用pyproject.tomlpixi.toml配置

  7. 可选择任何构建后端


不足之处:与其他工具兼容性有限,且没有遵循 Conda 的全局环境理念。


3. 工具选择建议


如此之多的依赖管理工具,我们应该如何选择呢?


如果我们的项目只有对 Python 包的依赖,那么推荐uvPixi

如果需要维护多个互斥的环境,那么推荐pip + venv + pip-tools + pyenv

如果需处理无法通过 pip 安装的依赖,那么建议使用Pixi


4. 总结


Python的依赖管理工具很多,但是大部分工具其实大同小异,只是互相做了一些小的改进。


我们选择时,除了考虑遗留项目的问题之外,尽量优先选择新出的工具。


新的工具除了会改进原有工具的缺点,还会借鉴其他语言的优秀的依赖管理工具。


目前,我个人的话,使用uv来管理项目比较多。


文章转载自:wang_yb

原文链接:https://www.cnblogs.com/wang_yb/p/18617458

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
从混沌到秩序:Python的依赖管理工具分析_Python_不在线第一只蜗牛_InfoQ写作社区