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

整合了 pipvirtualenvpip-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来管理项目比较多。

从混沌到秩序:Python的依赖管理工具分析的更多相关文章

  1. Composer : php依赖管理工具

    原始时代 我记得在当时用php的时候还没有composer,只有个pear,但是不好用呀,还不如直接在互联网上到处复制代码了,更快更不容易出错,当时也没有github这么好的社区工具了 总结如下 代码 ...

  2. Python的包管理工具

    Python的包管理工具 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么使用包管理 Python的模块或者源文件直接可以复制到目标项目目录中,就可以导入使用了. 但是为了 ...

  3. Python的包管理工具Pip (zz )

    Python的包管理工具Pip 接触了Ruby,发现它有个包管理工具RubyGem很好用,并且有很完备的文档系统http://rdoc.info 发现Python下也有同样的工具,包括easy_ins ...

  4. composer php依赖管理工具

    #composer是什么 Composer 是 PHP 的一个依赖管理工具.它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们. composer出现之前我们php项目依赖管理大部分都是手动 ...

  5. Go 包依赖管理工具 —— govendor

    govendor 是一个基于 vendor 机制实现的 Go 包依赖管理命令行工具.与原生 vendor 无侵入性融合,也支持从其他依赖管理工具迁移,可以很方便的实现同一个包在不同项目中不同版本.以及 ...

  6. yarn依赖管理工具的使用

    Yarn是Facebook发布的一款依赖管理工具,它比npm更快.更高效. 与NPM命令对照 npm install => yarn install npm install --save [pa ...

  7. Golang依赖管理工具:glide从入门到精通使用

    这是一个创建于 2017-07-22 05:33:09 的文章,其中的信息可能已经有所发展或是发生改变. 介绍 不论是开发Java还是你正在学习的Golang,都会遇到依赖管理问题.Java有牛逼轰轰 ...

  8. PHP的依赖管理工具----composer

    安装Composer 参考:https://getcomposer.org/doc/01-basic-usage.md composer 是PHP依赖管理工具 PHP最低版本要求5.3.2,需要允许o ...

  9. 有用PHP依赖管理工具Composer新手教程

    PHP依赖管理工具Composer新手教程 Composer 是 PHP 的一个依赖管理工具.它同意你申明项目所依赖的代码库,它会在你的项目中为你安装他们. 依赖管理 Composer 不是一个包管理 ...

  10. golang多个项目时如何配置GOPATH,使用gb包依赖管理工具,不同项目配置不同的GOPATH的

    golang多个项目时如何配置GOPATH,使用gb包依赖管理工具,不同项目配置不同的GOPATH的 1:执行脚本setGoPath.sh#!/bin/bashif [[ $GOPATH =~ .*$ ...

随机推荐

  1. Android UsbDeviceManager 代码分析

    USBDeviceManager是一个Android系统中用于管理USB设备的类,它是系统服务之一.其主要功能是控制USB设备的连接和断开,以及管理USB设备的权限和状态.下面是对USBDeviceM ...

  2. 基于 Nginx 的大型互联网集群架构与实战方案

    1. Nginx 负载均衡基础配置 首先,搭建一个基础的 Nginx 负载均衡器,用于将流量分发到多个后端服务器上. 步骤 1.1:安装 Nginx 在每台要作为负载均衡器的服务器上,安装 Nginx ...

  3. 一文彻底弄懂spring boot自动转配的过程

    Spring Boot 的自动配置机制是它的重要特性之一,极大地简化了 Spring 应用的配置工作.自动配置的核心思想是基于类路径中的依赖.环境配置以及自定义代码进行智能化配置,避免了开发者手动编写 ...

  4. Git仓库操作笔记[Git repositories]

    指令操作:Git Bash 重点:远程库和本地库之间操作 首先得在github网站 上创建一个 repository ,才能同步. 命令前提是进入githubLib 下的当前目录. 1.从远程库克隆到 ...

  5. 2024年网鼎杯青龙组 pwn

    pwn2 开局泄露栈地址,又是栈溢出,直接栈转移拿下 from pwn import * from LibcSearcher import LibcSearcher #from Crypto.Util ...

  6. Java常见面试真题之中级进阶

    前言 本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!java反射的作用于原理?说说List,Set,Map三者的区别?Object 有哪些常用方法?大致说一下每个方法的含义?Java 创建对 ...

  7. luogu P3842 [TJOI2007] 线段

    link 好题,考虑如何设定状态. 设\(dp_{i,0/1}\)表示到了第\(i\)行走完后停在这一行的最左侧/最右侧. 设定\(l_i\)表示这一行该线段的最左侧,\(r_i\)表示这一行的最右侧 ...

  8. base64编码图片二进制数据后直接保存在html文件中

    相关内容: 在markdown编辑器中嵌入base64图片 看到一个帖子,那就是base64编码用来http服务中对二进制文件编码,那么可以不可以直接在html文件中使用base64编码后的字符串来表 ...

  9. 一款 C# 编写的神经网络计算图框架

    前言 深度学习技术的不断发展,神经网络在各个领域得到了广泛应用.为了满足 .NET 开发的需求,推荐一款使用 C# 编写的神经网络计算图框架. 框架的使用方法接近 PyTorch,提供了丰富的示例和详 ...

  10. Air780E量产binpkg文件如何获取

    ​ 今天我们学习Air780E量产binpkg文件如何获取: 一.背景 最近luatos开发客户增多,客户在量产烧录的时候需要binpkg文件,但是有些客户不知道binpkg文件是什么,在哪里获取,是 ...