从混沌到秩序:Python的依赖管理工具分析
Python 的依赖管理工具一直没有标准化,原因主要包括:
- 历史发展的随意性:
Python发展早期对于依赖管理的重视程度不足,缺乏从一开始就进行统一规划和设计的意识 - 社区的分散性:
Python社区庞大且分散,众多开发者和团队各自为政,根据自己的需求和偏好开发工具,缺乏统一的协调和整合机制 - 多样化的使用场景:
Python应用场景广泛,从 Web 开发到数据科学、机器学习、系统管理脚本等。不同场景对依赖管理有着不同的要求 - 向后兼容性的挑战:
Python语言本身非常注重向后兼容性,这在一定程度上限制了对依赖管理工具进行根本性变革的可能性 - 缺乏统一的治理:与一些编程语言(如
Java有 Oracle 主导的规范制定)不同,Python没有一个强有力的单一实体来主导依赖管理工具的标准化工作 - 生态系统的快速变化:
Python生态系统发展迅速,新的库和框架不断涌现,这使得依赖关系变得越来越复杂
1. 什么是依赖管理
依赖管理工具常用于处理软件项目中的依赖关系。
在软件开发过程中,一个项目往往会依赖于许多其他的软件库、框架或组件。
依赖管理工具能够帮助开发者精确地指定这些依赖项的版本,自动下载和安装它们,并且可以在不同的环境中(如开发、测试、生产环境)保证依赖项的一致性。
这样可以有效避免因依赖版本混乱而导致的软件故障、兼容性问题等情况。
比如,其他编程语言的标准依赖管理工具有:NodeJS的npm,Rust的cargo,Java的Maven等等。
依赖管理工具最关键的作用是可重复性,意味着我们可以遵循一系列步骤,最终得到的软件项目是完全相同的。
特别是现在的项目(不管是开源的还是内部的)基本都需要多人协作,确保每个人的代码编译出来的软件运行结果一致是至关重要的。
良好的依赖管理可以对开发、构建和部署阶段的所有依赖关系都明确声明,并与版本控制中的代码一起跟踪。
简单来说:应用程序=代码+所有依赖项。
具体可以归纳为以下几个步骤:
- 创建定义文件:项目的描述,声明所需的依赖项和最小版本约束等
- 生成锁定文件:固定依赖项的版本和依赖项之间的关系
- 同步环境:一般都过git之类的版本管理工具互相同步
- 追踪定义文件和锁定文件:定义文件和锁定文件有变化时及时互相同步
2. 依赖管理工具对比
Python 的依赖管理工具虽然没有统一,但是有很多可供选择,下面一一分析每个工具的优缺点。
2.1. pip
pip是自带的默认包管理器,也是使用最多的工具,它的特点是只能用来安装Python包。
优势:
- 自
Python 3.4起包含在Python中,无需额外安装 - 2013年开始引入
wheels分发格式,安装速度大大提高 - 2020年开始加入了依赖解析算法,能够更好的保持环境的一致性
不足之处:
- 依赖
Python,也就是说使用pip必须先安装Python - 不能安装非Python的包
- 没有锁定文件
2.2. venv
用于创建虚拟环境的内置工具,在虚拟环境中可使用 pip 安装包,通过设置环境变量来隔离环境。
优势:自Python 3.3起包含在Python中。
不足之处:
- 是
Python工具,依赖Python安装 - 所有环境必须使用相同的
Python解释器 - 无法安装非
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> 工具协同工作。
不足之处:
- 是
Python工具,需安装到项目环境中,可能存在兼容性问题 - 只能处理
pip可安装的包 - 定义文件需手动维护
2.5. Pipenv
整合了 pip、virtualenv 和 pip-tools 的功能,通过Pipfile和Pipfile.lock管理依赖和虚拟环境,自动更新文件。
优势:轻量、简单,包装了基本的 pip/venv 工具。
不足之处:
- 是
Python工具 - 有自己的定义和锁文件格式
- 只能处理
pip可安装的包 - 只能区分开发和非开发依赖,环境定义不够灵活
2.6. Poetry
旨在涵盖 Python 项目整个开发流程,包括项目引导、虚拟环境、依赖管理、构建和发布包。
通过pyproject.toml管理依赖,自动维护poetry.lock,支持依赖分组。
优势:
- 一体化工具,涵盖项目开发全生命周期
- 有方便的命令行界面
- 支持依赖分组
不足之处:
- 是
Python工具,较重量级,依赖多,安装可能有问题 - 与其他工具互操作性差,不支持其他构建后端
- 不支持维护互斥环境
- 有自己的依赖定义和锁文件格式
- 只能处理
pip可安装的包
2.7. PDM
类似于 Poetry,但遵循 PEP 标准,可使用uv进行依赖解析和安装,其构建后端可独立使用。
uv是后面将要介绍的另一个依赖管理工具。
优势:
- 遵循
PEP标准 - 可利用
uv进行依赖管理
不足之处:与 Poetry 类似,是 Python 工具,有较多依赖,存在相关缺点。
2.8. pyenv
用于安装和管理不同版本的 Python,可在全局或项目级别激活指定版本,是简单的 shell 实用程序,不依赖 Python 安装。
优势:
- 纯
shell脚本,无Python依赖 - 遵循
Unix哲学,专注于管理Python版本
不足之处:
- 安装新
Python版本需下载并编译源代码,耗时 - 首次设置可能较麻烦,需安装多个构建依赖
- 不支持
Windows
2.9. pipx
将 pip 包安装在用户级别的独立虚拟环境中,避免依赖冲突,通过 symlink(软链接) 将入口点链接到PATH,方便调用。
优势:比直接在用户级别 pip 安装工具更好,能隔离依赖,可使用不同 Python 解释器。
不足之处:
- 是
Python工具 - 无法安装同一工具的多个版本,所有项目需共享工具版本
2.10. uv
用 Rust 编写的全能工具,旨在替代多个 Python 管理工具,处理整个开发流程,包括安装包、管理虚拟环境、构建和发布等。
遵循 Python 标准,依赖定义在pyproject.toml,锁文件为uv.lock,支持任意依赖分组,能安装 pip 包作为可执行文件,可管理 Python 版本,维护全局包缓存。
优势:
- 用
Rust编写,速度极快,单二进制文件,无外部依赖 - 多平台支持
- 一体化工具,功能全面
- 遵循
Python标准 - 支持选择任何构建后端
- 支持依赖分组。
不足之处:
- 不支持维护多个互斥环境
- 只能处理
pip可安装的包
2.11. Conda
由 Anaconda 公司开发的不同生态系统的包管理器,主要用于安装anaconda.org上的包,
能创建虚拟环境,与 pip 生态系统不同,对【包】 的定义更广泛,包括共享库、头文件、可执行文件等。
优势:
- 多平台支持
- 有全局包缓存
- 包以编译二进制形式分发
- 依赖解析算法健壮
- 可在
Conda环境中使用pip - 支持全局和共享环境
不足之处:
- 速度慢
- 包的下载是串行的
- 安装过程有些侵入性,会修改
shell配置 - 与 “主”
Python生态系统互操作性有限 - 无锁文件
- 构建和分发
Conda包较痛苦
2.12. Mamba
是Conda的改进版,旨在解决Conda的痛点,如慢的依赖解析和并行下载问题,用 C++ 实现,使用不同算法,推荐安装方式已改变。
速度比Conda 快很多,其他方面和Conda类似。
2.13. Pixi
类似于 uv,但针对 Conda 生态系统,用 Rust 编写,支持多平台。
通过pyproject.toml或pixi.toml配置,有方便的命令行界面,支持管理多个虚拟环境和定义文件,有锁文件机制,支持类似 Makefile 的项目自动化任务,可指定系统依赖,但不帮助构建包。
优势:
- 用 Rust 编写,速度快,单二进制文件,无外部依赖
- 多平台支持
- 方便的命令行界面
- 全局包缓存
- 可下载
Python二进制文件和anaconda.org上的非Python包 - 能使用
pyproject.toml和pixi.toml配置 - 可选择任何构建后端
不足之处:与其他工具兼容性有限,且没有遵循 Conda 的全局环境理念。
3. 工具选择建议
如此之多的依赖管理工具,我们应该如何选择呢?
如果我们的项目只有对Python包的依赖,那么推荐uv和Pixi;
如果需要维护多个互斥的环境,那么推荐pip + venv + pip-tools + pyenv;
如果需处理无法通过 pip 安装的依赖,那么建议使用Pixi。
4. 总结
Python的依赖管理工具很多,但是大部分工具其实大同小异,只是互相做了一些小的改进。
我们选择时,除了考虑遗留项目的问题之外,尽量优先选择新出的工具。
新的工具除了会改进原有工具的缺点,还会借鉴其他语言的优秀的依赖管理工具。
目前,我个人的话,使用uv来管理项目比较多。
从混沌到秩序:Python的依赖管理工具分析的更多相关文章
- Composer : php依赖管理工具
原始时代 我记得在当时用php的时候还没有composer,只有个pear,但是不好用呀,还不如直接在互联网上到处复制代码了,更快更不容易出错,当时也没有github这么好的社区工具了 总结如下 代码 ...
- Python的包管理工具
Python的包管理工具 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么使用包管理 Python的模块或者源文件直接可以复制到目标项目目录中,就可以导入使用了. 但是为了 ...
- Python的包管理工具Pip (zz )
Python的包管理工具Pip 接触了Ruby,发现它有个包管理工具RubyGem很好用,并且有很完备的文档系统http://rdoc.info 发现Python下也有同样的工具,包括easy_ins ...
- composer php依赖管理工具
#composer是什么 Composer 是 PHP 的一个依赖管理工具.它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们. composer出现之前我们php项目依赖管理大部分都是手动 ...
- Go 包依赖管理工具 —— govendor
govendor 是一个基于 vendor 机制实现的 Go 包依赖管理命令行工具.与原生 vendor 无侵入性融合,也支持从其他依赖管理工具迁移,可以很方便的实现同一个包在不同项目中不同版本.以及 ...
- yarn依赖管理工具的使用
Yarn是Facebook发布的一款依赖管理工具,它比npm更快.更高效. 与NPM命令对照 npm install => yarn install npm install --save [pa ...
- Golang依赖管理工具:glide从入门到精通使用
这是一个创建于 2017-07-22 05:33:09 的文章,其中的信息可能已经有所发展或是发生改变. 介绍 不论是开发Java还是你正在学习的Golang,都会遇到依赖管理问题.Java有牛逼轰轰 ...
- PHP的依赖管理工具----composer
安装Composer 参考:https://getcomposer.org/doc/01-basic-usage.md composer 是PHP依赖管理工具 PHP最低版本要求5.3.2,需要允许o ...
- 有用PHP依赖管理工具Composer新手教程
PHP依赖管理工具Composer新手教程 Composer 是 PHP 的一个依赖管理工具.它同意你申明项目所依赖的代码库,它会在你的项目中为你安装他们. 依赖管理 Composer 不是一个包管理 ...
- golang多个项目时如何配置GOPATH,使用gb包依赖管理工具,不同项目配置不同的GOPATH的
golang多个项目时如何配置GOPATH,使用gb包依赖管理工具,不同项目配置不同的GOPATH的 1:执行脚本setGoPath.sh#!/bin/bashif [[ $GOPATH =~ .*$ ...
随机推荐
- Android UsbDeviceManager 代码分析
USBDeviceManager是一个Android系统中用于管理USB设备的类,它是系统服务之一.其主要功能是控制USB设备的连接和断开,以及管理USB设备的权限和状态.下面是对USBDeviceM ...
- 基于 Nginx 的大型互联网集群架构与实战方案
1. Nginx 负载均衡基础配置 首先,搭建一个基础的 Nginx 负载均衡器,用于将流量分发到多个后端服务器上. 步骤 1.1:安装 Nginx 在每台要作为负载均衡器的服务器上,安装 Nginx ...
- 一文彻底弄懂spring boot自动转配的过程
Spring Boot 的自动配置机制是它的重要特性之一,极大地简化了 Spring 应用的配置工作.自动配置的核心思想是基于类路径中的依赖.环境配置以及自定义代码进行智能化配置,避免了开发者手动编写 ...
- Git仓库操作笔记[Git repositories]
指令操作:Git Bash 重点:远程库和本地库之间操作 首先得在github网站 上创建一个 repository ,才能同步. 命令前提是进入githubLib 下的当前目录. 1.从远程库克隆到 ...
- 2024年网鼎杯青龙组 pwn
pwn2 开局泄露栈地址,又是栈溢出,直接栈转移拿下 from pwn import * from LibcSearcher import LibcSearcher #from Crypto.Util ...
- Java常见面试真题之中级进阶
前言 本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!java反射的作用于原理?说说List,Set,Map三者的区别?Object 有哪些常用方法?大致说一下每个方法的含义?Java 创建对 ...
- luogu P3842 [TJOI2007] 线段
link 好题,考虑如何设定状态. 设\(dp_{i,0/1}\)表示到了第\(i\)行走完后停在这一行的最左侧/最右侧. 设定\(l_i\)表示这一行该线段的最左侧,\(r_i\)表示这一行的最右侧 ...
- base64编码图片二进制数据后直接保存在html文件中
相关内容: 在markdown编辑器中嵌入base64图片 看到一个帖子,那就是base64编码用来http服务中对二进制文件编码,那么可以不可以直接在html文件中使用base64编码后的字符串来表 ...
- 一款 C# 编写的神经网络计算图框架
前言 深度学习技术的不断发展,神经网络在各个领域得到了广泛应用.为了满足 .NET 开发的需求,推荐一款使用 C# 编写的神经网络计算图框架. 框架的使用方法接近 PyTorch,提供了丰富的示例和详 ...
- Air780E量产binpkg文件如何获取
今天我们学习Air780E量产binpkg文件如何获取: 一.背景 最近luatos开发客户增多,客户在量产烧录的时候需要binpkg文件,但是有些客户不知道binpkg文件是什么,在哪里获取,是 ...