Python的新锐工具:uv 的介绍、使用示例、及注意事项一文详解。
在 Python 生态系统中,uv 是一个由 Astronomer 团队开发的高性能 Python 包管理和项目管理工具,旨在替代传统的 pip、venv 和 pipenv 等工具。
它基于 Rust 编写,执行速度快,功能强大,专注于提供更高效、简洁的 Python 开发工作流。uv 的主要功能包括:
- 包管理:快速安装、卸载和更新 Python 包。
- 虚拟环境管理:自动创建和管理虚拟环境。【生态不如anaconda成熟,建议这部分可以继续用conda】
- 依赖解析:高效解析项目依赖,解决依赖冲突。
- 项目管理:支持 Python 项目配置(如 pyproject.toml),提供类似 poetry 的功能。
- 跨平台支持:在 Windows、macOS 和 Linux 上运行良好。
通俗解释
你可以把 uv 想象成一个“超级管家”:它帮你快速整理 Python 项目,管理依赖(比如哪些库需要安装),还能自动创建虚拟环境(一个隔离的 Python 运行空间),避免不同项目的依赖冲突。
相比传统的 pip 和 venv,uv 更快、更智能,操作也更简单。它的核心优势是速度快(因为用 Rust 写成)和一体化(把多种工具的功能整合在一起)。
比如,你用 pip install 装包可能要等几秒甚至几十秒,而 uv 通常只需要零点几秒。它还能自动帮你管理项目的依赖版本,确保你的代码在不同电脑上跑的时候不会出问题。
举例说明
安装 uv
首先,你需要安装 uv,通常通过以下命令:
pip install uv
示例 1:快速安装 Python 包
假设你想安装 requests 库,传统方式是用 pip install requests,而用 uv 可以这样:
uv pip install requests
- 特点:速度比 pip 快很多,尤其是安装复杂依赖时。
- 输出:uv 会快速解析依赖并安装,可能只需 0.2 秒,而 pip 可能需要 2-3 秒。
示例 2:创建并管理虚拟环境
如果你想为一个新项目创建虚拟环境并安装依赖:
# 创建一个新项目目录并进入 mkdir my-project cd my-project # 初始化虚拟环境并安装依赖 uv venv # 创建虚拟环境 uv pip install numpy pandas
- 特点:uv 自动创建虚拟环境(默认在 .venv 目录下),无需手动运行 python -m venv 或激活环境。
- 结果:你在 my-project 中有了一个隔离的 Python 环境,安装了 numpy 和 pandas。
示例 3:管理项目依赖
假设你有一个 pyproject.toml 文件,定义了项目的依赖:
[project] name = "my-app" version = "0.1.0" dependencies = [ "fastapi>=0.68.0", "uvicorn>=0.15.0" ]
可以用 uv 来安装所有依赖:
uv sync
- 特点:uv sync 会根据 pyproject.toml 安装所有依赖,并确保版本一致。它还会生成一个 requirements.lock 文件,锁定具体版本,方便团队协作或部署。
- 结果:你的项目依赖被快速安装,且版本完全可控。
示例 4:运行 Python 脚本
uv 还支持直接运行 Python 脚本或命令,自动使用虚拟环境:
uv run my_script.py
- 特点:无需手动激活虚拟环境,uv 会自动在正确的环境中运行脚本。
- 结果:你的脚本在隔离的虚拟环境中运行,避免依赖冲突。
总结
uv 是一个现代化的 Python 工具,目标是让开发者更省心、更高效。它整合了包管理、虚拟环境管理和项目配置的功能,速度快,使用简单。
对于新手来说,它减少了手动操作的麻烦;对于专业开发者来说,它提供了强大的依赖管理和锁文件功能,适合复杂项目。
追问1:我之前使用的习惯是 pip+anaconda,如果换成UV,该怎么组合使用?又能带来哪些方便?
基于我的习惯使用 pip + Anaconda 来管理 Python 包和环境。现在需要知晓如何将 uv 与 Anaconda 结合使用,以及这种组合能带来哪些便利。
以下我会详细说明如何在 Anaconda 环境中使用 uv,分析其优势,并通过与 pip + Anaconda 的对比举例说明 uv 带来的方便之处。
如何在 Anaconda 中使用 uv
Anaconda 提供了一个强大的 Python 环境管理工具(conda),而 uv 是一个高性能的包管理和虚拟环境工具。两者可以结合使用,uv 主要接管 pip 的功能,同时保留 Anaconda 的环境管理能力。以下是具体步骤和使用方式:
- 安装 uv 在 Anaconda 环境中
- 激活你想要使用的 Anaconda 环境:
conda activate myenv
在该环境中安装 uv:
pip install uv
- 这样,uv 就安装在指定的 Anaconda 环境中,可以用于包管理和虚拟环境操作。
- 使用 uv 管理包
- 在 Anaconda 环境中,你可以用 uv pip 替代 pip 来安装、卸载或更新包。例如:
uv pip install numpy pandas
- uv 会将包安装到当前 Anaconda 环境的 site-packages 目录中,与 pip 行为一致,但速度更快。
- 结合 Anaconda 虚拟环境
- 你仍使用 conda 创建和管理虚拟环境,例如:
conda create -n myenv python=3.10
conda activate myenv
- 在激活的环境中,使用 uv pip 安装依赖,而不是 pip。uv 会自动识别当前环境并将包安装到对应的 Anaconda 环境中。
- 项目管理(可选)
- 如果你的项目有 pyproject.toml 文件,uv 可以直接管理项目依赖:
uv sync
- 这会根据 pyproject.toml 安装依赖,并生成锁文件(如 requirements.lock),确保依赖版本一致。
- 运行脚本
- 使用 uv run 运行 Python 脚本,uv 会自动使用当前 Anaconda 环境的 Python 解释器:
uv run my_script.py
uv + Anaconda 带来的便利
与传统的 pip + Anaconda 组合相比,uv + Anaconda 提供了以下优势:
- 更快的包安装速度:uv 使用 Rust 编写,依赖解析和安装速度远超 pip,尤其在安装复杂依赖时。
- 更高效的依赖解析:uv 的依赖解析器能更快解决冲突,避免 pip 常见的依赖版本问题。
- 虚拟环境自动化:uv 可以自动创建和管理虚拟环境,减少手动操作。
- 锁文件支持:uv 支持生成 requirements.lock,确保依赖版本在不同机器上完全一致,适合团队协作和生产部署。
- 跨工具兼容性:uv 支持 pyproject.toml 和 requirements.txt,与 Anaconda 的 conda 环境无缝集成。
- 更简洁的命令:uv 整合了包管理、虚拟环境和脚本运行的功能,命令更统一,减少切换工具的麻烦。
举例对比说明
以下通过几个常见场景,对比 pip + Anaconda 和 uv + Anaconda 的使用方式和效果。
示例 1:安装复杂依赖
场景:你需要为一个机器学习项目安装 tensorflow、numpy 和 pandas。
- 使用 pip + Anaconda:
conda activate ml_env
pip install tensorflow numpy pandas
-
- 耗时:假设安装需要 10-20 秒(依赖解析和下载较慢)。
- 问题:pip 可能遇到依赖冲突,需要手动指定版本(如 pip install tensorflow==2.12.0)。
- 输出:安装完成后,依赖可能不完全兼容,需手动调试。
- 使用 uv + Anaconda:
conda activate ml_env
uv pip install tensorflow numpy pandas
-
- 耗时:通常只需 2-5 秒(uv 的依赖解析和下载速度极快)。
- 优势:uv 自动解析兼容版本,减少冲突概率。安装完成后,依赖更可能直接可用。
- 输出:安装日志简洁,显示解析和下载的进度,体验更流畅。
示例 2:管理项目依赖
场景:你有一个项目,pyproject.toml 中定义了依赖:
[project] name = "my-ml-project" dependencies = [ "fastapi>=0.100.0", "uvicorn>=0.20.0", "numpy>=1.26.0" ]
使用 pip + Anaconda:
- 需要手动将 pyproject.toml 转换为 requirements.txt(或逐个安装):
conda activate myenv
pip install fastapi uvicorn numpy
-
- 问题:
- 没有自动锁文件,可能导致不同机器上的依赖版本不一致。
- 安装速度较慢(可能 10-15 秒)。
- 手动管理依赖版本,容易出错。
- 结果:可能需要额外工具(如 pipdeptree)检查依赖,或手动调整版本。
- 问题:
- 使用 uv + Anaconda:
conda activate myenv
uv sync
-
- 优势:
- uv 自动读取 pyproject.toml,安装所有依赖并生成 requirements.lock,确保版本一致。
- 安装速度快(通常 2-3 秒)。
- 自动处理依赖冲突,减少手动干预。
- 结果:生成锁文件,依赖版本可复现,适合团队协作或 CI/CD 流程。
- 优势:
示例 3:运行脚本
场景:你有一个脚本 train.py,需要运行在特定 Anaconda 环境中。
- 使用 pip + Anaconda:
conda activate myenv
python train.py
-
- 问题:
- 需要手动激活环境,容易忘记。
- 如果环境配置错误,可能运行失败。
- 无法直接确认脚本依赖是否齐全。
- 问题:
- 使用 uv + Anaconda:
uv run --with-venv myenv train.py
-
- 优势:
- uv 自动使用 myenv 环境的 Python,无需手动激活。
- 如果脚本依赖缺失,uv 可以提示并快速安装。
- 命令更简洁,适合自动化脚本或 CI/CD。
- 结果:运行更顺畅,减少环境切换的麻烦。
- 优势:
示例 4:迁移到新机器
场景:你需要将项目迁移到新机器,确保依赖一致。
- 使用 pip + Anaconda:
- 导出依赖:
conda activate myenv
pip freeze > requirements.txt
新机器上安装:
conda create -n myenv python=3.10
conda activate myenv
pip install -r requirements.txt
-
- 问题:
- pip freeze 可能包含冗余依赖,导致 requirements.txt 不准确。
- 安装速度慢,依赖冲突可能需要手动解决。
- Anaconda 环境和 pip 依赖可能不完全同步。
- 问题:
- 使用 uv + Anaconda:
- 导出锁文件:
conda activate myenv uv pip compile pyproject.toml -o requirements.lock
- 新机器上安装:
conda create -n myenv python=3.10
conda activate myenv
uv pip sync requirements.lock
-
- 优势:
- requirements.lock 精确锁定依赖版本,确保一致性。
- 安装速度快,依赖解析更可靠。
- uv 的锁文件格式更清晰,适合跨平台迁移。
- 结果:新机器上的环境快速复现,无需手动调试依赖。
- 优势:
注意事项
- Conda vs. uv 的虚拟环境:
- 建议继续使用 conda 管理虚拟环境,因为 Anaconda 的环境隔离更成熟,兼容性更好。uv 的虚拟环境功能(uv venv)更适合非 Anaconda 项目。
- 不要混用 conda install 和 uv pip install 安装同一包,可能导致版本冲突。优先使用 uv pip install 管理 PyPI 包。
- Anaconda 渠道包:
- 某些包(如 pytorch)可能需要通过 conda install 从 Anaconda 渠道安装,因为 PyPI 版本可能不兼容 GPU 驱动。uv 目前主要管理 PyPI 包,遇到此类情况仍需用 conda。
追问2:如何理解如下这句话?
没有自动锁文件,可能导致不同机器上的依赖版本不一致。
为什么说“没有自动锁文件,可能导致不同机器上的依赖版本不一致”?
在 Python 的 pip + Anaconda 组合中,pip 本身不会自动生成一个精确的依赖版本锁文件(lock file)。
锁文件的作用是记录项目中所有依赖包的具体版本号(包括直接依赖和间接依赖),以确保在不同机器或环境中复现完全相同的依赖环境。
如果没有锁文件,依赖版本可能会因为以下原因在不同机器上不一致:
- pip 的依赖解析不固定:
- pip install 在安装包时,会根据当时 PyPI 仓库中的最新版本或约束条件(如 >=)动态解析依赖。
- 如果没有明确指定版本(如 numpy==1.26.0),pip 可能会安装不同版本,导致不同机器上的环境不一致。
- pip freeze 的局限性:
- 虽然可以用 pip freeze > requirements.txt 导出依赖,但它只记录当前环境中已安装的包和版本,不区分直接依赖和间接依赖。
- requirements.txt 不是真正的锁文件,因为它可能包含不必要的包(比如手动安装的临时工具),或者缺少动态解析的上下文信息。
- Anaconda 和 PyPI 混用问题:
- 在 Anaconda 环境中,conda 和 pip 可能分别从 Anaconda 渠道和 PyPI 安装包,版本可能不完全同步。
- 没有锁文件记录完整的版本信息,可能导致不同机器上依赖来源或版本不一致。
- 时间变化导致版本更新:
- PyPI 上的包会不断更新。如果你在不同时间或机器上运行 pip install,可能会安装不同版本的包(比如 numpy 从 1.26.0 更新到 1.26.4),导致环境差异。
举例说明
场景:迁移项目到新机器
假设你有一个机器学习项目,依赖 numpy 和 scikit-learn,在 Anaconda 环境中使用 pip 安装。
使用 pip + Anaconda
- 在机器 A 上开发:
- 你激活 Anaconda 环境并安装依赖:
conda activate myenv
pip install numpy scikit-learn
- 假设安装了 numpy==1.26.0 和 scikit-learn==1.2.0(以及其间接依赖,如 scipy==1.10.0)。
- 导出依赖:
pip freeze > requirements.txt
生成的 requirements.txt 可能如下:
numpy==1.26.0 scikit-learn==1.2.0 scipy==1.10.0 joblib==1.2.0 threadpoolctl==3.1.0
-
- 问题:
- pip freeze 包含了所有已安装的包,包括间接依赖(scipy、joblib 等),但不区分哪些是你主动需要的,哪些是自动安装的。
- 如果环境中安装了其他无关的包(比如你临时装了 requests),也会被记录,增加冗余。
- 问题:
在新机器 B 上复现:
-
- 你创建相同的 Anaconda 环境:
conda create -n myenv python=3.10
conda activate myenv
pip install -r requirements.txt
可能的问题:
- 如果 PyPI 或 Anaconda 仓库中的包更新了,比如 numpy 更新到 1.26.4 或 scikit-learn 更新到 1.3.0,pip 可能会安装新版本,导致版本不一致。
- 如果机器 B 的 Anaconda 渠道优先级高于 PyPI,可能安装 Anaconda 版本的 numpy(比如 1.26.2),而不是 PyPI 的 1.26.0。
- 如果 requirements.txt 包含冗余包(如 requests),新机器也会安装这些无关包,浪费资源或引发冲突。
- 结果:
- 机器 A 和机器 B 的环境可能有不同版本的依赖(比如 numpy==1.26.0 vs. numpy==1.26.4)。
- 如果新版本有不兼容的 API 变化(比如 scikit-learn 的参数调整),你的代码可能在新机器上运行失败。
使用 uv + Anaconda
- 在机器 A 上开发:
- 你在 Anaconda 环境中使用 uv 安装依赖,并生成锁文件:
conda activate myenv uv pip install numpy scikit-learn uv pip compile pyproject.toml -o requirements.lock
假设你的 pyproject.toml 定义了:
[project] name = "my-ml-project" dependencies = [ "numpy>=1.26.0", "scikit-learn>=1.2.0" ]
uv 生成的 requirements.lock 会精确记录所有依赖的版本,比如:
numpy==1.26.0 scikit-learn==1.2.0 scipy==1.10.0 joblib==1.2.0 threadpoolctl==3.1.0
-
- 优势:
- 锁文件只记录项目实际需要的依赖及其精确版本,排除无关包。
- uv 的依赖解析更快(通常 1-2 秒 vs. pip 的 5-10 秒),生成锁文件时会验证所有依赖的兼容性。
- 优势:
在新机器 B 上复现:
-
- 你创建 Anaconda 环境并使用 uv 同步依赖:
conda create -n myenv python=3.10
conda activate myenv
uv pip sync requirements.lock
-
- 优势:
- uv pip sync 严格按照 requirements.lock 安装,精确复现机器 A 的依赖版本(numpy==1.26.0,scikit-learn==1.2.0 等)。
- 即使 PyPI 或 Anaconda 仓库更新了包版本,uv 也不会安装新版本,而是严格遵循锁文件。
- 安装速度快,减少等待时间。
- 优势:
- 结果:
- 机器 B 的环境与机器 A 完全一致,依赖版本相同(numpy==1.26.0,scikit-learn==1.2.0 等)。
- 你的代码在新机器上运行时,不会因为版本差异导致错误。
- 锁文件还便于团队协作或 CI/CD 流程,确保所有开发者和服务器使用相同的依赖环境。
总结
pip + Anaconda 缺乏自动锁文件,导致依赖版本可能因时间、机器或仓库差异而变化,造成环境不一致。
uv 通过 requirements.lock 精确锁定所有依赖版本,结合 Anaconda 的环境管理能力,确保跨机器的可复现性,减少调试成本。
上述例子展示了 uv 如何在迁移项目时保证一致性,同时提升安装速度和依赖管理效率。

浙公网安备 33010602011771号