从pip到UV:新一代包管理器的高效替代方案
大多数Python开发者在管理环境和依赖的工具方面面临碎片化问题。可用的工具有很多——pip、virtualenv、Poetry和conda。所有这些工具都有各自的构建方式和要求。然而,当它们被组合使用时,你会很快发现它们如何让必要的工作流程变得复杂。
这正是UV发挥作用的地方,它将成为你需要的唯一真正的Python包管理器。
对于不了解的人来说,UV是一款现代高性能的Python包管理器,用Rust编写。不必考虑其他工具,UV的目标是将所有这些工具的功能整合为一个统一的体验,只需通过一个终端命令即可启动。
UV由Astral开发,旨在对标pip、virtualenv、pip-tools和pyenv的部分功能,目标是成为一款在依赖与环境管理方面全面超越的、显著更快的一体化工具!
目录
文章目录
- 目录
- 什么是UV?
- UV与Poetry、PIP+Virtualenv、Conda的对比:差异所在
- UV与PIP和virtualenv对比
- UV相比pip + virtualenv的优势
- UV与pip + virtualenv示例对比
- Conda与UV对比
- UV相比Conda的优势
- UV与Conda示例对比
- UV与Poetry对比
- Poetry的优势
- Poetry的劣势
- UV相比Poetry的优势
- 示例对比
- UV入门指南:简单教程
- 步骤1:安装UV
- 步骤2:创建新项目
- 步骤3:为项目添加初始依赖
- 步骤4:使用UV运行Python脚本
- 使用UV管理Python版本
- 列出已安装的Python版本
- 为当前项目切换Python版本
- 检查当前活动版本
- 理解UV工具
- UV中的锁定文件是什么?
- 锁定文件与requirements.txt的对比
- 使用UV进行高级依赖管理
- 更新依赖
- 添加可选依赖
- 依赖组
- 从PIP和Virtualenv迁移到UV
- 转换现有virtualenv项目
- 替换常用的pip/virtualenv命令
- 结论
什么是UV?
从黑箱视角看,UV是一款用Rust编写的现代高性能Python包管理器和安装工具。它可以直接替代pip等传统Python包管理器,提供相当或更优的速度、更高的可靠性以及一致的依赖解析能力。UV旨在解决Python生态中最突出的痛点:漫长的安装时间、依赖解析陷阱以及企业级环境管理的复杂性!所有这些痛点都是UV的典型应用场景,其独特的架构和精心设计的实现使其能够实现快速速度和高效的包工作流——它的速度可能比现有包管理工具快10-100倍!
UV的目标是通过集成以下功能来简化常见的Python开发工作流:
- 安装包:类似于pip。
- 管理环境:替代virtualenv。
- 锁定依赖:提供pip-tools或Poetry的功能以实现可复现构建。
- 管理Python版本:作为pyenv的替代方案。
与独立运行的传统工具不同,UV为Python开发提供了一个“开箱即用”的集成式解决方案。它旨在减少开发者需要管理的工具和命令数量。
使UV脱颖而出的关键特性包括:
- 闪电般快速的包安装和依赖解析。
- 与现有Python工具和工作流兼容。
- 内置虚拟环境管理。
- 支持现代打包标准。
- 可靠的依赖锁定和可复现环境。
- 内存高效运行(尤其适用于大型项目)。
无论是开发小型个人项目还是管理大规模Python应用,UV都能作为Python包管理器提供强大而高效的解决方案。
UV与Poetry、PIP+Virtualenv、Conda的对比:差异所在
开发者在切换到新工具前常问的第一个问题是:“它与我当前使用的工具有何不同?”在Python依赖和项目管理领域,pip、Poetry、Conda和virtualenv是最常用的工具。然而,在当今可用的Python包管理器中,UV有其独特优势。
下表突出了UV在现有Python管理工具中的定位:
功能 | UV | pip + virtualenv | Poetry | Conda |
---|---|---|---|---|
实现语言 | Rust | Python | Python | Python + C++ |
速度 | 比pip快10-100倍 | 基准速度 | 比pip快 | 比pip慢 |
内存占用 | 非常高效 | 较高 | 中等 | 高 |
环境管理 | 内置 | 需要单独工具 | 内置 | 内置 |
依赖解析 | 快速现代解析器 | 基础解析 | 现代解析器 | 全面解析 |
非Python包支持 | 不支持 | 不支持 | 不支持 | 支持 |
锁定文件 | 支持(uv.lock) | 不支持(基础requirements.txt) | 支持 | 支持 |
项目结构规范 | 支持 | 不支持 | 支持 | 不支持 |
包发布 | 支持 | 支持(需twine) | 支持 | 支持 |
兼容性 | 兼容现有pip生态 | 标准Python工具 | 更严格的规范 | 自有生态 |
错误处理 | 清晰的错误信息 | 基础 | 良好 | 良好 |
资源占用 | 最小 | 中等 | 中等 | 高 |
科学计算聚焦 | 不支持 | 不支持 | 不支持 | 支持 |
跨平台一致性 | 支持 | 有限 | 良好 | 优秀 |
通过此表,我们将逐一探讨这些工具与UV的优缺点对比。
UV与PIP和virtualenv对比
pip和virtualenv一直是Python环境和包管理的独立工具。其中,pip专门用于包管理,virtualenv专门用于隔离环境。以下是它们组合使用的优缺点速览:
类别 | 优势 | 劣势 |
---|---|---|
pip + virtualenv | – 经过多年采用的成熟生态 – 大量文档和社区支持 – 对基础项目简单有效 | – 环境搭建和包安装需分开操作 – 对大型/复杂项目依赖解析慢 – 无内置锁定文件保证可复现性 |
UV相比pip + virtualenv的优势
以下是UV明显更优的几个方面:
- 单一工具:UV同时用于创建环境和包安装。一个命令(uv)即可完成两项任务,减少整体工作流。
- 现代并行依赖解析器:UV的解析器采用现代算法,可更快安装依赖(在可能时并行安装)。
- 锁定文件(uv.lock):UV自动生成锁定文件,确保每次安装相同版本的包,提升可复现性。
UV与pip + virtualenv示例对比
使用pip + virtualenv搭建环境并安装包需要:
virtualenv env
source env/bin/activate
pip install -r requirements.txt
使用UV则只需运行:
uv env create
uv install
UV通常比pip + virtualenv安装更快,且通过生成的锁定文件保证不同机器上安装的包版本完全一致。
Conda与UV对比
Conda是一款多功能的强大环境和包管理器,在科学界和数据科学领域广泛使用。它支持所有包(不仅限于Python包),包括系统级依赖和系统库——这些对执行复杂科学计算工作流至关重要。
以下是Conda在Python开发中的优缺点:
类别 | 优势 | 劣势 |
---|---|---|
Conda | – 支持CUDA、BLAS、编译器等非Python包 – 跨项目强环境隔离 – 跨Windows、macOS、Linux的一致行为 – 简化Python版本切换 | – 因二进制大小和解析复杂度导致安装慢 – 占用更多磁盘空间和内存 – 可能滞后于PyPI的最新包版本 |
UV相比Conda的优势
以下是UV超越Conda的方面:
- 闪电般的包安装和环境搭建速度:UV用Rust实现,优化了并行下载和安装逻辑,显著提升环境创建速度,提高开发者效率。
- 最小内存和CPU占用:UV在操作时使用更少资源,适用于资源受限的机器或CI流水线(资源使用至关重要)。
- 完全兼容Python打包标准:UV基于与现有Python工具(如requirements.txt和PyPI索引)相同的打包标准构建,开发者无需切换到新生态或维护额外包列表。
- 更易集成现有Python工作流:由于UV仅关注Python包,不会引入系统级依赖管理的额外复杂性,可无缝集成到典型Python开发环境。
UV与Conda示例对比
使用Conda搭建环境通常如下:
conda create -n myenv python=3.9 numpy scipy
conda activate myenv
而使用UV的流程是:
uv env create -p python=3.9
uv install numpy scipy
Conda在科学和数据科学项目中非常强大,因为它能管理系统级包并在同一环境中支持多种平台。但Conda在安装速度和内存使用上存在不足,这在某些场景下值得注意。
相比之下,当安装速度、低开销和保持Python生态内操作是首要需求时,UV尤为有用。此外,当项目没有大量非Python依赖时,使用UV仍具优势(此时Conda仍有其用武之地)。
UV与Poetry对比
Poetry是一款现代的一体化Python包管理器,以结构化、规范化的方式处理依赖管理、项目脚手架和包发布。
另请阅读:如何用Poetry构建RAG评估器Python包?
类别 | 优势 | 劣势 |
---|---|---|
Poetry | – 强大的依赖解析器处理复杂版本冲突 – 内置项目脚手架促进清晰结构 – 集成PyPI发布简化部署 – 生成 poetry.lock 实现可复现构建 | – 规范化结构可能降低灵活性 – 对大型项目依赖解析较慢 – 与混合pip工作流存在兼容性问题 |
Poetry的优势
以下是Poetry的显著优点:
- 强大的依赖解析器:Poetry能处理依赖间的复杂版本冲突,确保依赖平滑协作。
- 内置项目结构:Poetry提供项目脚手架并规定项目布局,便于维护一致的项目结构。
- 集成发布功能:Poetry包含发布包到PyPI的命令,使发布变得简单。
- 可复现性:生成poetry.lock文件以实现跨机器的可复现环境。
Poetry的劣势
Poetry的局限性包括:
- 规范化工作流:Poetry的约定可能降低开发者自定义项目配置的灵活性。
- 依赖解析较慢:Poetry的依赖解析器可能比UV慢,导致大型项目安装依赖耗时更长。
- 兼容性问题:Poetry的约定有时会修改“常规”的pip工作流,可能阻碍与其他工具的集成。
UV相比Poetry的优势
以下是UV作为Python包管理器超越Poetry的原因:
- 极快的依赖解析:UV通过Rust实现的快速计算能力解析和安装依赖,创建环境的时间仅为传统Python包管理器的零头。
- 轻量高效:使用极少系统资源快速构建环境。
- 兼容标准Python打包:与强制开发者按其约定管理环境和项目的Poetry不同,UV兼容现有的requirements.txt和setup.py,极易于与pip及现有工具集成。
- 灵活的项目结构:与Poetry不同,UV不规定特定格式,允许开发者逐步采用,无需改变项目习惯。
示例对比
使用Poetry创建项目并添加依赖:
poetry new myproject
cd myproject
poetry add requests flask
poetry install
Poetry同时管理项目结构和环境。使用UV时,可在已构建的项目中安装依赖:
uv install requests flask
UV专注于快速安装和环境管理,不“规定”结构布局,其非结构化特性使其易于逐步采用。
UV入门指南:简单教程
现在你决定尝试将UV作为下一个Python包管理器。这是明智的选择,以下是操作步骤。
步骤1:安装UV
在macOS和Linux上可通过终端使用curl安装:
curl -LsSf https://astral.sh/uv/install.sh | sudo sh
在Windows上(需以管理员权限运行),使用PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
也可使用Homebrew安装:
brew install uv
支持pip安装,但不推荐。安装后,通过检查版本确认工作正常:
uv version
步骤2:创建新项目
要使用UV创建新项目,需导航到已有项目目录或新建目录:
mkdir myproject
cd myproject
uv init
例如,若运行uv init explore-uv
,将创建名为explore-uv的新项目。该命令会创建项目目录(explore-uv)并自动生成以下文件:
- .gitignore
- .python-version
- README.md
- hello.py(示例文件)
- pyproject.toml(项目元数据和依赖的主配置文件)
步骤3:为项目添加初始依赖
UV通过一个命令(uv add)将环境创建和依赖添加结合:
uv add scikit-learn xgboost
首次执行uv add时,UV会在当前工作目录创建新虚拟环境并安装指定依赖。后续运行uv add时,将使用现有虚拟环境并安装/更新新请求的包。
UV使用及时的现代依赖解析器,分析整个依赖图并找到兼容的包版本以避免版本冲突。每次add命令结束后,UV会更新pyproject.toml和uv.lock文件(记录安装的版本),保持准确记录。
要移除依赖及其子依赖,运行uv remove:
uv remove scikit-learn
步骤4:使用UV运行Python脚本
安装依赖后,可使用uv run代替python script.py运行Python脚本:
uv run hello.py
该命令确保脚本在UV创建的项目虚拟环境中运行。
使用UV管理Python版本
以下是UV简化Python版本管理的几种方式。
列出已安装的Python版本
UV可检测机器上已存在或已安装的Python版本:
uv python list --only-installed
此命令将显示UV找到的所有Python版本列表,包括通过Conda或Homebrew安装的版本。
为当前项目切换Python版本
只要新版本满足pyproject.toml中的requires-python规范(如requires-python = “>=3.9”),即可随时为UV项目切换Python版本。
设置Python版本:
uv python use 3.11
这会将Python版本嵌入到.python-version文件中以保持一致性。若找不到请求的版本,UV会下载并安装到~/.local/share/uv/python。然后,UV会在项目目录创建新虚拟环境并替换旧环境。更新Python版本后,可能需要重新安装依赖:
uv pip install -e .
若遇到权限被拒绝的错误,可能需要使用sudo(macOS/Linux)或以管理员身份运行命令提示符(Windows)。更好的方法是更改UV主目录的所有权:
sudo chown -R $USER ~/.local/share/uv # macOS或Linux
检查当前活动版本
uv python --version
理解UV工具
UV工具还提供接口来管理那些暴露为命令行工具的Python包(如black、flake8、pytest…)。
Black是流行的Python代码格式化工具,可自动重新格式化代码以遵循一致风格,提高可读性并保持项目代码风格统一。
uv tool run
告诉UV运行一个工具(此处工具名是black,Python代码格式化工具),hello.py是要格式化的目标文件。该命令会在hello.py文件上运行Black,按Black的风格规则自动格式化。
使用uv tool run
:
uv tool run black hello.py
使用更短的uvx
命令:
uvx black hello.py
运行这些命令时,UV会在其缓存中创建临时虚拟环境,安装工具并从该环境运行。这允许你使用命令行工具而无需将其安装到项目虚拟环境中,从而加快执行速度并保持项目依赖清洁。这些缓存环境会在UV清理缓存时自动删除,非常适合偶尔使用开发工具的场景。
UV中的锁定文件是什么?
锁定文件(uv.lock)是UV依赖管理的重要组成部分。每次运行uv add命令时,UV会创建和/或更新uv.lock文件。uv.lock文件:
- 跟踪并记录所有依赖及其子依赖的精确版本。
- 通过“锁定”环境间的依赖版本实现可复现构建。
- 防止“依赖地狱”,保持包版本一致。
- 允许更快安装(因为UV可使用已锁定的版本,无需重新解析依赖)。
UV自动跟踪锁定文件,你应将其提交到版本控制以确保开发团队间的依赖版本一致。
锁定文件与requirements.txt的对比
锁定文件和requirements.txt都处理依赖,但用途不同:
功能 | uv.lock | requirements.txt |
---|---|---|
可复现性 | 高 | 低到中等 |
生成方式 | UV解析器自动生成 | 手动或pip freeze生成 |
可编辑性 | 否(自动生成) | 是 |
锁定文件是开发的重要组成部分,有助于建立可复现构建。requirements.txt文件比锁定文件简单,通常仅包含直接依赖(因其被更广泛的Python工具识别),可作为与不使用UV的最终用户共享/部署代码的方式。你可以同时维护两者:使用UV锁定文件进行开发,部署时生成requirements.txt如下:
uv export -o requirements.txt
使用UV进行高级依赖管理
UV提供复杂的dependencies管理方法:
更新依赖
add命令可用于更新、修改约束或指定现有依赖的精确版本:
安装最新版本:
uv add requests
安装特定版本:
uv add requests=2.1.2
修改约束范围:
uv add 'requests<3.0.0'
使依赖平台特定:
uv add 'requests; sys_platform="linux"'
添加可选依赖
可选依赖是核心功能不需要但特定功能需要的包(如Pandas的excel或plot附加功能)。
首先安装核心包:
uv add pandas
然后添加其可选依赖:
uv add pandas --optional plot excel
这些会在pyproject.toml的[project.optional-dependencies]部分列出。
依赖组
依赖组允许你组织依赖(如开发、测试和文档依赖),以将生产依赖与其他依赖分离。
要将新依赖安装到特定组,使用–group标志:
uv add --group group_name package_name
用户可使用–group、–only-group和–no-group标志进一步控制安装的组。
从PIP和Virtualenv迁移到UV
从pip和virtualenv迁移到UV几乎是无缝的,因为UV基于现有Python打包标准构建。
转换现有virtualenv项目
若有现有项目:
pip freeze > requirements.txt
接下来,在同一目录初始化新UV项目:
uv init .
现在可从需求文件安装依赖:
uv pip install -r requirements.txt
替换常用的pip/virtualenv命令
以下是替换常用pip/virtualenv命令的快速参考:
pip/virtualenv命令 | UV等效命令 |
---|---|
python -m venv .venv | uv venv |
pip install package | uv add package |
pip install -r requirements.txt | uv pip install -r requirements.txt |
pip uninstall package | uv remove package |
pip freeze | uv pip freeze |
pip list | uv pip list |
迁移后,可安全删除旧的virtualenv目录。若需要回退到传统pip命令,可使用UV内置的pip兼容层。
结论
在众多Python包管理器中,UV脱颖而出,为包管理提供了比传统工具更现代、快速和有效的替代方案。UV的主要优势包括:
- 卓越性能(比pip快10-100倍)。
- 兼容当前Python打包标准。
- 内置虚拟环境支持。
- 极高效的依赖解析和锁定文件支持。
- 小内存占用和资源消耗。
无论是启动新项目还是升级现有项目,UV都是能提升Python开发工作流的可靠解决方案。由于它兼容现有工具和流程,对于希望将开发工具链带入21世纪而不破坏工作流的开发者来说,是一个简单的选择。
作为开发者,我们生活在一个不断演进的环境中。UV这样的工具展示了Rust等现代语言如何提升开发者体验,同时保留Python开发者依赖的简便性和可访问性。