极快的python项目管理工具:uv使用指南

上一篇文章介绍了新一代的 Python 项目管理工具 Poetry,解决了 Python 项目难以管理的问题。本文将介绍另一款 Python 项目管理工具 uv,uv 是由 Astral 团队打造的下一代 Python 项目与包管理工具,目标是替代 pip、pip-tools 和 virtualenv ,为 Python 生态带来更快的依赖解析和安装体验。
uv 官网的介绍是 用 Rust 编写的极快速的 Python 打包和项目管理工具。uv 之所以快,不仅因为用 Rust 重构,还在于其全局缓存与依赖解析算法优化。uv 仍在快速迭代中,强烈推荐 Python 开发者使用。
版本信息
- OS: Debian 13 (Trixie)
- Python: 3.13
- uv: 0.10.7
安装 uv
建议用 pipx 安装 uv
$ pipx install uv -i https://mirrors.aliyun.com/pypi/simple
$ uv --version
uv 0.10.7
uv help 可以列出 uv 支持的所有命令。
$ uv help
...
run Run a command or script
init Create a new project
add Add dependencies to the project
remove Remove dependencies from the project
version Read or update the project's version
sync Update the project's environment
lock Update the project's lockfile
...
项目管理
uv 既可以用于新项目,也可以快速适配到已有的 Python 项目中。其用法十分简单直观。
创建项目
无论是创建新项目,还是将已有项目交给 uv 管理,都使用 uv init 命令。区别在于:创建新项目需要传递项目名(即目录名);初始化已有项目则不需要任何参数。
下面创建一个新项目,看看 uv 做了哪些事。
$ uv init newproj
Initialized project `newproj` at `/tmp/newproj`
$ ls -a newproj
. .. .git .gitignore main.py pyproject.toml .python-version README.md
$ cd newproj
$ uv run main.py
Using CPython 3.13.5 interpreter at: /usr/bin/python3.13 # 使用系统中的Python版本
Creating virtual environment at: .venv # 创建虚拟环境
Hello from newproj! # 虚拟环境中运行脚本
$ uv run which python # 虚拟环境中的Python
/tmp/newproj/.venv/bin/python # 实际是 /usr/bin/python3.13 的软链接
- 使用
uv init创建名为 newproj 的新项目。可以用--python 3.xx指定虚拟环境 Python 版本;不指定时使用系统全局版本。 - 查看新项目目录内容:
.git和.gitignore是基础的 Git 目录和文件;.gitignore内含常见忽略项,例如__pycache__/、.venv。main.py是示例脚本,包含基础main函数。pyproject.toml是 PEP 定义的标准项目配置文件,uv 大多数操作都围绕它展开。.python-version记录项目使用的 Python 版本,例如 3.13。README.md是项目说明文档,默认为空。
- 使用
uv run <command>会在当前 uv 环境中运行命令,并自动创建.venv目录和uv.lock文件。
pyproject.toml 内容很精简,仅包含基本项目信息,建议按实际需要调整。
[project]
name = "newproj"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = []
uv init 可通过参数决定项目类型,不同类型的目录结构略有区别:
--bare:仅创建pyproject.toml,不创建其他文件和目录。--package:创建src布局目录(如src/包名)。pyproject.toml额外包含[project.scripts]和[build-system],用于运行和打包。--lib:与--package类似,但不包含[project.scripts]。--app:应用类型项目,默认结构。采用扁平布局,无src目录,pyproject.toml中也没有运行或打包配置段。--script:不创建pyproject.toml,仅创建一个脚本文件,文件开头包含注释形式的pyproject.toml片段,用于管理脚本依赖。
这些选项仅决定初始化时的目录结构,项目用途与使用方式仍可按需调整。
PyPI 源
国内从官方 PyPI 源安装依赖通常较慢,可设定国内镜像作为默认源以提升速度。在 pyproject.toml 中添加:
[[tool.uv.index]]
name = "aliyun"
url = "https://mirrors.aliyun.com/pypi/simple"
default = true
安装和卸载
uv 使用 add 和 remove 管理依赖的安装与卸载。
进入 newproj 目录,安装依赖:
$ uv add aiohttp httpx
$ grep -A3 ^dependencies pyproject.toml
dependencies = [
"aiohttp>=3.13.3",
"httpx>=0.28.1",
]
安装的依赖会记录在 pyproject.toml 中。版本区间写法如 >=3.13,<3.15,该写法可用于 Python 版本约束与依赖版本约束。
卸载依赖:
$ uv remove aiohttp
$ grep -A3 ^dependencies pyproject.toml
dependencies = [
"httpx>=0.28.1",
]
卸载后,只剩一项依赖。
在添加或删除依赖时,uv 会完成 3件事:
- 将依赖下载到 uv 的用户级全局缓存中,并从缓存安装到虚拟环境。
- 将依赖写入
pyproject.toml。 - 将依赖解析结果写入
uv.lock。uv.lock是项目依赖快照,包含直接与间接依赖、来源、版本与哈希等信息。
uv 还提供几种常见的依赖安装方式:
从 requirements.txt 文件中安装依赖,并写入 pyproject.toml:
$ uv add -r requirements.txt
也可以将 uv.lock 中的依赖导出为 requirements.txt 格式:
$ uv export --format requirements.txt
升级特定依赖:
$ uv add --upgrade requests
将项目上传到 Git 仓库时,不应提交 .venv 目录,一般只需要提交 pyproject.toml 和 uv.lock。运行时基于 uv.lock,uv sync 能快速恢复项目依赖,精确到每个依赖的具体版本。
$ uv sync
查看项目的依赖关系树形图
$ uv tree
newproj v0.1.0
└── httpx v0.28.1
├── anyio v4.12.1
│ └── idna v3.11
├── certifi v2026.2.25
├── httpcore v1.0.9
│ ├── certifi v2026.2.25
│ └── h11 v0.16.0
└── idna v3.11
依赖组
添加两个依赖组,分别为 dev 和 test,用于管理开发与测试阶段依赖。
$ uv add ruff --group dev
$ uv add pytest --group test
uv add
--group dev 等价于 uv add --dev <PACKAGES>。
检查 pyproject.toml 文件内容,依赖组定义在 dependency-groups 中:
$ grep -A6 dependency-groups pyproject.toml
[dependency-groups]
dev = [
"ruff>=0.15.5",
]
test = [
"pytest>=9.0.2",
]
uv sync 提供以下选项以决定安装哪些依赖组:
--no-dev: 禁用dev依赖组。--only-dev:仅包含dev依赖组--group <GROUP>:指定特定依赖组,--no-group <NO_GROUP>:排除指定依赖组--no-default-groups:排除默认的依赖组--only-group <ONLY_GROUP>:仅包含特定的依赖组--all-groups:安装所有依赖组。
除了依赖组 dependency-groups 之外,uv 还支持可选依赖(optional dependencies)。两者用法相近,但职责不同:
dependency-groups用--group之类的参数控制;optional dependencies用--extra <EXTRA>控制。dependency-groups记录在pyproject.toml的[dependency-groups]表中;optional dependencies记录在[project.optional-dependencies]中。dependency-groups一般用于开发、测试、CI 等阶段依赖;optional dependencies更适合库项目的可选功能(如不同数据库后端)。
uv 各子命令对 dependency-groups 与 optional dependencies 的操作支持相对一致,可按项目需求选择。
uv.lock
uv.lock 记录当前解析出的依赖集合,是项目依赖的快照。使用 uv sync 可恢复出一致的项目环境,对应用类型的 Python 项目尤其有用。
如果 uv.lock 丢失,可用 uv lock 重新生成 uv.lock。
$ uv lock
可以手动编辑 pyproject.toml, 但千万不要手动编辑 uv.lock 文件
link-mode 与缓存
uv 可通过环境变量控制行为,其中 UV_LINK_MODE 用于决定从全局缓存安装软件包的方式,可选值有 clone、copy、hardlink、symlink。从缓存获取依赖,是 uv 速度提升的重要原因之一。
clone:将源目录中的包克隆(写入时复制)到目标目录,默认选项。copy:将包从源位置复制到目标位置。hardlink:将源包硬链接到目标位置。symlink:将源目录中的包以符号链接方式指向目标目录。不建议使用此模式,清理缓存可能导致依赖失效。
除了环境变量,uv 也支持使用 --link-mode 指定模式,该行为也可写入 pyproject.toml:
[tool.uv]
link-mode = "copy"
uv cache dir 查看缓存目录位置:
$ uv cache dir
~/.cache/uv
uv cache size 查看缓存大小:
$ uv cache size --human
26.7MiB
uv cache clean 清理缓存。可指定删除特定包,默认删除全部缓存。
$ uv cache clean # 清理系统的全部缓存
$ uv cache size --human # 查看清理后,缓存大小为0
0
uv cache prune 命令比uv cache clean 智能一些,只会清理不再使用的缓存包。
除 --link-mode 外,uv 还支持 --offline 模式禁用网络,仅使用本地缓存安装依赖;若依赖缺失则直接报错。该行为也可在 pyproject.toml 中配置:
[tool.uv]
offline = true
虚拟环境
uv 不仅可以使用系统中已有的 Python,还能从 uv 的 Github 仓库中在线下载和安装指定版本的 Python。
Python 版本管理
uv 支持在线下载并安装指定的 Python 版本。查看 uv 安装 Python 的路径:
$ uv python dir
~/.local/share/uv/python
查看当前已安装和可安装的版本列表:
$ uv python list
cpython-3.15.0a6-linux-x86_64-gnu <download available>
cpython-3.15.0a6+freethreaded-linux-x86_64-gnu <download available>
cpython-3.14.3-linux-x86_64-gnu <download available>
cpython-3.14.3+freethreaded-linux-x86_64-gnu <download available>
cpython-3.13.12-linux-x86_64-gnu <download available>
cpython-3.13.12+freethreaded-linux-x86_64-gnu <download available>
cpython-3.13.5-linux-x86_64-gnu /usr/bin/python3.13 # 系统的全局 Python 版本
...
在线安装 Python
$ uv python install 3.14
在项目中临时使用 Python 3.14 运行:
$ uv run --python 3.14 python -c 'import sys; print(sys.version)'
3.14.3 (main, Feb 12 2026, 00:42:54) [Clang 21.1.4 ]
修改当前项目运行的 Python 版本:
$ uv python pin 3.14
Pinned `.python-version` to `3.14`
$ uv run python --version
Python 3.14.3
使用 uv python pin 3.14 会更新项目目录下的 .python-version 为 3.14。由于仍满足 pyproject.toml 中 requires-python = ">=3.13" 的要求,所以无需修改 pyproject.toml。若不满足约束,会报兼容性错误,需要手动修改 pyproject.toml 的限制条件。
uv pip
使用 uv pip ... 在虚拟环境中安装包:
$ uv pip install ipython
$ uv pip list | grep ipython
ipython 9.11.0
注意:使用 uv pip install 安装的软件包不会记录到 pyproject.toml 和 uv.lock 中,执行 uv sync 时会被移除。
uv 的其他用法
除了上面的基础项目管理和虚拟环境等基础功能外,uv 还有一些其他很有用的玩法。
uv format
uv format 命令可以用于代码的格式化,底层使用 ruff ,支持如下两个参数:
--check:检查代码是否已经符合格式要求,不执行格式化--diff:以 diff 的形式显示 format 将会对代码做哪些变动。
不加参数的情况下,uv format 会默认自动对代码做格式化。也可以仅对指定 Python 文件做 format 格式化。
uv 会自动寻找项目目录下和全局的 ruff 配置文件(比如:~/.config/ruff/ruff.toml),以便确定 ruff 的 format 规则。
uvx 和 uv tool
uv tool 是 uv 提供的全局工具箱管理,用于安装或在隔离环境中运行 Python CLI 工具,功能类似 pipx。子命令包括:
install/uninstall/list/upgrade:安装/卸载/列表/升级工具run:运行工具,等价于uvx。工具不存在时会自动安装到缓存并运行。dir:查看工具安装路径。
uv tool run(即 uvx)的目标是“无需安装、即时运行”。它会创建临时环境用于运行,环境会被缓存以便复用,非常适合偶尔使用的工具。
uv tool install 则将工具安装为全局可用命令。
查看工具安装的目录
$ uv tool dir
~/.local/share/uv/tools
使用 uvx 和 uv tool run 临时安装并运行 httpx 工具:
$ uv tool run httpx[cli] http://xnow.me # uv tool run 临时安装和测试
$ uvx httpx[cli] http://xnow.me # uvx 临时安装和测试
$ uv tool list # 工具列表为空
安装 httpx 工具并检查安装路径:
$ uv tool install httpx[cli] --force # 安装 httpx 工具
$ uv tool list # 检查工具列表,其中包含了 httpx
httpx v0.28.1
- httpx
$ which httpx # 已经有了全局的 httpx 命令
~/.local/bin/httpx
$ ls -lh ~/.local/bin/httpx # 检查全局 httpx 命令,来自于 uv tool 目录下
lrwxrwxrwx 1 1000 1000 48 Mar 8 16:40 ~/.local/bin/httpx -> ~/.local/share/uv/tools/httpx/bin/httpx
因此,如果要经常使用的命令,建议用 uv tool install 做安装和使用。
为特定依赖使用特定源
PyTorch 官方源有些奇怪,默认的 PyPI 中只有 GPU 版本的依赖库,如果要安装 CPU 版本的PyPI,则需要指定专门支持 CPU 的 PyPI 源。因此,可以在 ptproject.toml 中添加专门的源,并指定 torch 包使用这个源安装。配置如下:
[tool.uv.sources]
torch = { index = "pytorch-cpu" }
[[tool.uv.index]]
name = "pytorch-cpu"
explicit = true
url = "https://download.pytorch.org/whl/cpu"
某些场景下建议显式使用 PyTorch 官方 index,效果等价于
-i https://download.pytorch.org/whl/cpu。
explicit = true表示默认不使用该源,只有明确指定时才会使用。
run 的临时依赖
如果不想将临时依赖写入 dev 依赖组,可用 --with 临时指定,例如为 Flask 的 shell 使用 IPython:
$ FLASK_APP=hello.py uv run --with flask-shell-ipython flask shell
uv 脚本
uv 的脚本管理功能在运维脚本场景中非常实用。使用 uv 初始化脚本时,脚本自动内置依赖管理,不创建 pyproject.toml。
$ uv init --script test.py # 初始化脚本
Initialized script at `test.py`
$ cat test.py # 查看脚本内容
# /// script
# requires-python = ">=3.13"
# dependencies = []
# ///
def main() -> None:
print("Hello from test.py!")
if __name__ == "__main__":
main()
test.py 如果不存在, uv 会自动创建,内容如上。如果 test.py 脚本已经存在, uv 会在脚本已有内容的基础上,在文件开头增加依赖管理相关的注释行。
可以手动或使用 uv 命令为该文件管理依赖:
$ uv add requests --script test.py
$ grep dependencies test.py -A 2
# dependencies = [
# "requests",
# ]
$ uv run test.py
Installed 5 packages in 23ms
Hello from test.py!
uv add requests --script test.py会将依赖更新到脚本文件开头。uv run test.py会解析脚本中定义的依赖并创建虚拟环境。脚本虚拟环境位于~/.cache/uv/environments-v2/,不同脚本之间彼此隔离。
如果觉得频繁使用 uv run 不便,可在脚本第一行添加 shebang:#!/usr/bin/env -S uv run。授予可执行权限后,./a.py 等价于 uv run a.py。
使用 uv lock --script test.py 会创建或更新 test.py.lock,记录脚本依赖及版本。
探索 uv 的其他用法
uv 项目仍在快速发展中,有些使用方法还在预览阶段。如果遇到问题,建议到 uv 的官方文档中寻求解答。uv 的配置项和环境变量尤其有用,建议看看。
uv 配置项:https://docs.astral.sh/uv/reference/settings/ uv 环境变量:https://docs.astral.sh/uv/reference/environment/
uv 的优势在于“快”和“可重复”。无论是日常开发还是脚本工具化,uv init/add/sync 覆盖了大多数场景,配合 uv.lock 能稳定复现依赖环境。
总结
本文从日常开发需求入手,介绍了 uv 在 Python 项目开发各个阶段的用法。不论是初级还是资深Python研发工程师,都建议尝试uv,随着 uv 的发展,应该会有更多惊艳功能出现。
Last updates at Mar 09,2026
Views (25)
total 0 comments