
大多数 Python 开发者都在处理环境和依赖项管理工具的碎片化问题。市面上有很多工具可供使用,例如 pip、virtualenv、Poetry 和 conda。所有这些工具都有各自的结构和要求。然而,当它们组合使用时,你很快就会发现它们会使任何必要的工作流程变得复杂。而这正是 UV 能够助你一臂之力的地方,它就是你所需要的真正的 Python 包管理器。
对于那些不了解 UV 的人来说,它是一款用 Rust 编写的现代高性能 Python 包管理器。无需理会其他工具,UV 的目标是将所有这些工具的功能整合到一个只需一个终端命令即可打开的条件式体验中。UV 由 Astral 开发,旨在与 pip、virtualenv、pip-tools 和 pyenv 的各个方面进行基准测试,最终目标是成为一款速度更快的一体化依赖项和环境管理工具!
UV是什么?
UV 是一个黑盒程序,它是一款用 Rust 编写的现代高性能 Python 包管理器和安装程序。它是 pip 等传统 Python 包管理器的直接替代品。它提供类似甚至更佳的速度、更高的可靠性以及依赖项解析的一致性。UV 旨在解决 Python 生态系统中一些最明显的痛点。漫长的安装时间、依赖项解析的陷阱以及企业级环境管理的复杂性!所有这些痛点都是 UV 的典型用例,它拥有独特的架构和周到的实现,以实现快速高效的包工作流程。它的速度比现有的包管理器快 10 到 100 倍!
UV 的目标是通过提供以下集成功能来简化常见的 Python 开发工作流程:
- 安装包:类似于 pip。
- 环境管理:虚拟环境的替代品。
- 锁定依赖项:提供 pip-tools 或 Poetry 的功能,以实现可重复的构建。
- Python 版本管理:提供 pyenv 的替代方案。
与传统独立运行的工具不同,UV 提供了一种统一的、“batteries-included”的 Python 开发方法。它旨在减少开发人员需要管理的工具和命令数量。
UV 的主要优势包括:
- 闪电般的软件包安装和依赖项解析。
- 兼容现有的 Python 工具和工作流程。
- 内置虚拟环境管理。
- 支持现代打包标准。
- 可靠的依赖项锁定和可复现的环境。
- 内存高效运行,尤其适用于大型项目。
无论是处理小型个人项目还是管理大型 Python 应用程序,UV 作为 Python 包管理器都能提供强大而高效的解决方案。
UV、Poetry、PIP + Virtualenv和Conda:区别
开发人员在切换到新工具之前经常会问的第一个问题是“它与我目前使用的工具相比如何?”。在 Python 依赖项和项目管理领域,pip、Poetry、Conda 和 virtualenv 已经是最常用的工具。然而,UV 在当今可用的 Python 包管理器中也有其自身的优势。
下表突出显示了 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 | – 成熟的生态,已被多年采纳 – 文档与社区支持丰富 – 适用于基础项目,简单有效 |
– 环境配置与包安装需要分开执行多个步骤<br>– 面对大型或复杂项目,依赖解析较慢 – 缺少内置锁定文件,不利于可复现性 |
UV相比pip + virtualenv的优势
以下是 UV 明显优于 pip + virtualenv 的一些方面:
- 单一工具: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 更快地完成安装,并使用生成的 lockfile 确保在不同机器上安装完全相同的软件包版本。
Conda vs UV
Conda 是一个功能强大且功能多样的环境和软件包管理器,在科学界和数据科学领域被广泛使用。它旨在支持所有软件包(不仅仅是 Python 软件包),包括对执行更复杂的科学计算工作流程至关重要的系统级依赖项和系统库。
以下是 Conda 在 Python 开发中的优缺点。
| 类别 | 优势 | 劣势 |
|---|---|---|
| Conda | – 支持非 Python 包,如 CUDA、BLAS、编译器 – 强大的项目间环境隔离 – 在 Windows、macOS 和 Linux 上行为一致 – 简化 Python 版本切换 |
– 由于二进制体积和解析器复杂性,包安装较慢 – 消耗更多磁盘空间和内存 – 可能在最新包版本上落后于 PyPI |
UV优于Conda
UV的优势如下:
- 闪电般的软件包安装和环境设置:UV 采用 Rust 语言实现,优化了并行下载,并加快了软件包安装和环境创建的速度,从而显著提升了环境的创建速度。开发人员将受益于生产力的提升。
- 极低的内存和 CPU 使用率:UV 在执行操作时消耗更少的内存和 CPU 资源,即使在资源非常紧张的机器上或在 CI 流水线中,每项资源的使用都至关重要,也能高效运行。
- 完全兼容 Python 打包标准:UV 基于与所有现有 Python 工具和格式(例如 requirements.txt 和 PyPI 索引)相同的打包标准构建。这使得开发人员无需迁移到新的生态系统或维护软件包列表即可使用 UV。
- 更易于集成到现有的 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 在安装速度和内存占用方面存在一些缺点,在某些情况下可能值得注意。
相比之下,UV 在安装速度、低开销以及保持 Python 生态系统是主要考虑因素的情况下尤其有用。此外,当项目没有太多非 Python 依赖项时,使用 conda 仍然非常有用且有利。
UV与Poetry对比
Poetry 是一款现代化的一体化 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 强制开发人员按照其约定管理其 Python 环境和项目不同,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 安装 UV:
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 脚本,而无需使用 python script.py 命令:
uv run hello.py
此命令确保脚本在 UV 创建的项目虚拟环境中运行。
使用UV管理Python版本
以下是 UV 流线与 Python 版本协同工作的一些方法。
列出现有的Python版本
UV 可以检测您计算机上现有或已安装的 Python 版本:
uv python list --only-installed
此命令将显示 UV 找到的所有 Python 版本的列表,包括通过 Conda 或 Homebrew 安装的版本。
更改当前项目的Python版本
您可以随时为 UV 项目切换 Python 版本,只要新版本满足 pyproject.toml 文件中的 require-python 规范(例如,requires-python = “>=3.9”)。
设置 Python 版本:
uv python use 3.11
这会将 Python 版本嵌入到 .python-version 中,并保持一致性。如果找不到请求的版本,UV 会下载并安装到 ~/.local/share/uv/python 中。然后,UV 会在项目目录中创建一个新的 venv 文件并替换旧版本。更新 Python 版本后,您可能需要重新安装依赖项:
uv pip install -e .
如果遇到与“权限被拒绝”相关的错误,您可能需要使用 sudo (macOS/Linux) 或以管理员身份运行命令提示符 (Windows)。更好的选择是更改 UV 主目录的所有权:
sudo chown -R $USER ~/.local/share/uv # macOS or 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 |
| 可编辑性 | 否(自动生成) | 是 |
前者,即 Lock 文件,是开发的重要组成部分,因为它们有助于建立可重复的构建。requirements.txt 文件比 lock 文件简单一些,通常只包含直接依赖项,因为它们在 Python 工具中被更广泛地识别,并且可以作为与不使用 UV 的最终用户共享/部署代码的一种方式。您可以使用 UV lock 文件进行开发,并在部署时生成如下的 requirements.txt 文件来维护两者:
uv export -o requirements.txt
使用UV进行高级依赖管理
UV 提供了完善的依赖管理方法:
更新依赖项
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 |
迁移完成后,您可以安全地删除旧的虚拟环境目录。如果您发现需要回退到传统的 pip 命令,可以随时使用 UV 内置的 pip 兼容层。
小结
UV 在众多 Python 包管理器中脱颖而出,与之前的工具相比,它提供了一种现代、快速且高效的包管理替代方案。UV 的主要优势包括:
- 卓越的性能(比 pip 快 10 到 100 倍)。
- 兼容当前的 Python 打包标准。
- 内置虚拟环境支持。
- 极其高效的依赖项解析和锁文件支持。
- 内存占用和资源消耗极小。
无论您是启动一个全新的项目还是升级现有项目,UV 都是一个可靠的解决方案,可以改善您的 Python 开发工作流程。由于它与现有工具和流程兼容,因此对于希望在不中断工作流程的情况下将其开发工具链带入 21 世纪的开发者来说,这是一个轻松的决定。
作为开发者,我们生活在一个不断发展的环境中。像 UV 这样的工具就是 Rust 等现代语言如何提升开发者体验的典范。同时,它还保留了 Python 开发者所依赖的易用性和可访问性。
既然您已经了解了 UV 作为 Python 包管理器的显著优势,不妨在您的下一个项目中尝试一下。请务必查看官方 GitHub 代码库,了解最新更新或贡献。此外,请与开发社区分享您的经验,以帮助扩大 UV 的采用率并促进其未来的增强功能。


评论留言