
如果你用 Python 工作过一段时间,你可能为了让几个项目跑起来而同时摆弄过 pip、virtualenv、pip-tools、pipx 和 pyenv。这些工具各管一件事,把它们串起来既慢又脆弱。uv 是一个能替代它们全部的单文件二进制程序。它由 Rust 编写,由 Astral(ruff 背后的团队)发布,在常见工作流中通常比 pip 快十倍到一百倍。
本指南讲解如何在 Linux 上安装 uv、用它创建和管理 Python 项目、添加依赖、使用虚拟环境,以及安装特定的 Python 版本。
快速参考
| Command | Description |
|---|---|
uv init my-project | 使用 pyproject.toml 创建新项目 |
uv add requests | 添加依赖并更新锁文件 |
uv add --dev pytest | 添加开发依赖 |
uv remove requests | 移除依赖 |
uv sync | 从锁文件安装依赖 |
uv lock | 更新锁文件 |
uv run script.py | 在项目环境中运行命令 |
uv venv | 创建虚拟环境 |
uv pip install requests | 兼容 pip 的安装接口 |
uv python install 3.12 | 安装特定 Python 版本 |
uv python list | 列出已安装与可用的 Python 版本 |
uv python pin 3.13 | 将项目固定到某 Python 版本 |
uv tool install ruff | 全局安装 CLI 工具 |
uvx ruff check . | 免安装临时运行工具 |
uv self update | 将 uv 更新到最新版本 |
uv cache clean | 清理 uv 缓存 |
安装 uv
在 Linux 上,推荐的安装方式是 Astral 提供的独立脚本。它会下载一个预编译二进制文件,放到 ~/.local/bin,且无需预先安装 Python:
curl -LsSf https://astral.sh/uv/install.sh
|
sh
如果未安装 curl,wget 也能完成同样的任务:
wget -qO- https://astral.sh/uv/install.sh
|
sh
脚本会打印二进制文件的位置,以及它是否更新了你的 shell 配置文件。重新加载 shell 或运行 source ~/.bashrc 使新的 PATH 生效,然后验证安装:
uv --version
uv 0.12.12
若想固定到特定版本,而不是每次都取最新版,可以把版本号写进 URL。这在 CI runner 和共享构建机上很重要,因为一次未声明的升级可能改变锁文件的解析结果:
curl -LsSf https://astral.sh/uv/0.12.12/install.sh
|
sh
安装程序默认写入 ~/.local/bin,并可能修改你的 shell 配置文件。设置 UV_INSTALL_DIR 可把二进制放到其他位置,设置 UV_NO_MODIFY_PATH=1 则不改动你的 shell 文件。以下命令将 uv 安装到用户可写的 ~/bin 目录:
curl -LsSf https://astral.sh/uv/install.sh
|
env
UV_INSTALL_DIR
=
"
$HOME
/bin"
UV_NO_MODIFY_PATH
=
1
sh
由于该命令禁用了自动 PATH 修改,如果 ~/bin 还不在 PATH 中,请自行将其加入 PATH。
如果你更倾向从包管理器安装,uv 也可以通过 pip、pipx 和 Homebrew 获取:
pip install uv
pipx install uv
brew install uv
在 Ubuntu、Debian 及其衍生版上,pip 可能因为 Python 环境被标记为 externally managed 而拒绝系统级安装。此时请使用 pipx install uv 或独立安装脚本。关于 pip 与 apt 的指南解释了现代发行版为何会封禁这条安装路径。
如果你已经拥有 Rust 工具链,可以从源码构建 uv,不过这比下载预编译二进制文件耗时得多:
cargo install --locked uv
Ubuntu 和 Debian 软件仓库中的 uv
一个常见问题是 uv 能否通过 apt 安装。Ubuntu 24.04、25.10 和 26.04 都不提供 Astral 的 uv CLI,Debian 12 和 Debian 13 同样没有。在这些发行版上,请改用独立安装脚本或 pipx。
Debian testing 和 unstable 含有一个名为 uv 的源码包,但目前只构建出 python3-uv-build 包。该包提供 Python 构建后端,并不安装 uv 命令。26.04 之后的 Ubuntu 开发系列有一个提供完整 CLI 的独立包,但它落后于上游版本。在你的发行版档案收录该 CLI 包之前,独立安装脚本仍是务实之选。
确实存在一些更紧跟上游的第三方 apt 仓库。它们既不由 Astral 也不由发行版维护,因此在把它们加入重要机器之前,请像对待任何其他外部仓库一样谨慎。
通过 Snap 安装 uv
在运行 snapd 的 Ubuntu 及其他发行版上,uv 可从 Snap Store 获取:
sudo snap install astral-uv --classic
需要 classic 限制级别,因为 uv 会写入你的项目目录和主目录缓存,而严格受限的 snap 无法访问这些位置。该 snap 名为 astral-uv,但它注册了 uv 和 uvx 别名,因此你之后输入的仍是常用命令。此包由社区贡献者而非 Astral 维护,不过它紧跟上游版本。
更新与卸载 uv
如果你用独立安装脚本安装了 uv,可用以下命令将其更新到最新版本:
uv self update
该命令仅适用于独立安装。当 uv 来自 pip、pipx、Homebrew、Cargo 或 Snap 时,请通过相同的工具升级,例如 pipx upgrade uv、brew upgrade uv 或 sudo snap refresh astral-uv。对包管理器安装的 uv 运行 uv self update 会报错,而不会在你包管理器背后替换二进制文件。
通过安装它们的同一个工具卸载包管理器安装的 uv。根据你选择的方式,使用 pip uninstall uv、pipx uninstall uv、brew uninstall uv、cargo uninstall uv 或 sudo snap remove astral-uv。
对于独立安装,先查看哪些受管的 Python 版本和工具将被移除:
uv python list --only-installed
uv tool list
确认不再需要它们后,在 uv 仍在你的 PATH 中时移除缓存、受管 Python 版本和已安装的工具:
uv cache clean
rm -r
"
$(
uv python dir
)
"
rm -r
"
$(
uv tool dir
)
"
接下来,从默认安装目录删除二进制文件:
rm ~/.local/bin/uv ~/.local/bin/uvx
如果你安装时设置了 UV_INSTALL_DIR,请从该目录移除二进制文件。
项目的虚拟环境不受影响,因为每个虚拟环境都位于各自项目目录下的 .venv 中。
启用 Shell 补全
uv 会生成自己的补全脚本。把对应你所用 shell 的那一行追加进去,然后打开一个新 shell 使其生效:
echo
'eval "$(uv generate-shell-completion bash)"'
>> ~/.bashrc
对于 Zsh,同样的写法适用于 ~/.zshrc:
echo
'eval "$(uv generate-shell-completion zsh)"'
>> ~/.zshrc
Fish 从其自有目录读取补全:
echo
'uv generate-shell-completion fish | source'
> ~/.config/fish/completions/uv.fish
uvx 是一个独立的二进制文件,拥有独立的补全,它采用 flag 形式而非子命令形式:
echo
'eval "$(uvx --generate-shell-completion bash)"'
>> ~/.bashrc
创建项目
uv init 会搭建一个新项目,并在其中初始化一个 Git 仓库:
uv init my-project
cd
my-project
Initialized project `my-project`
uv 默认创建一个打包项目,代码位于 src 下而非项目根目录:
my-project
├── .git
├── .gitignore
├── .python-version
├── README.md
├── pyproject.toml
└── src
└── my_project
└── __init__.py
my-project 中的连字符在模块名中会变成下划线,因为连字符在 Python 标识符中非法。.python-version 文件记录了项目期望的解释器,生成的 .gitignore 已排除 .venv 以及常见的构建产物。
生成的 pyproject.toml 包含项目元数据、一个入口点以及构建后端:
[
project
]
name
=
"my-project"
version
=
"0.1.0"
description
=
"Add your description here"
readme
=
"README.md"
requires-python
=
">=3.12"
dependencies
=
[]
[
project
.
scripts
]
my-project
=
"my_project:main"
[
build-system
]
requires
=
[
"uv_build>=0.12.12,<0.13"
]
build-backend
=
"uv_build"
requires-python 的值来自 uv 在系统中找到的解释器,因此你的可能与此处不同。如果你更想要扁平布局(项目根目录放一个 main.py,不使用构建系统,适合小型工具和一次性脚本),传入 --no-package:
uv init --no-package my-script
无论哪种方式,uv 尚未创建虚拟环境。这会在你首次添加依赖或在项目中运行命令时发生。
添加与移除依赖
要添加包,使用 uv add:
uv add requests
首次运行时,uv 会在项目根目录创建 .venv 目录,解析依赖图,写入一个把每个包及其传递性依赖都锁定的 uv.lock 文件,并将全部内容安装到 venv 中。requests 这一行也会被添加到 pyproject.toml 的 dependencies 下。
仅用于开发的依赖通过 --dev 放入一个独立分组:
uv add --dev pytest ruff
它们被记录在 pyproject.toml 的 dev 依赖组中,并安装到同一个 venv,但当你的项目作为库发布或安装时会被排除。
用 uv remove 移除依赖:
uv remove requests
uv 会更新 pyproject.toml、更新 uv.lock,并卸载该包以及任何不再需要的依赖。
在项目环境中运行代码
你无需手动激活虚拟环境。uv run 会在项目 venv 内执行命令,并在需要时先同步依赖。由于 uv init 写入了 [project.scripts] 入口,项目可以直接按名称运行:
uv run my-project
Hello from my-project!
同一条命令也适用于针对这些依赖运行的其他任务,例如测试套件:
uv run pytest
若要运行文件而非脚本入口点,通过 python 传入它。用 --no-package 创建的项目就是这样启动的,因为它们的代码放在顶层 main.py:
uv run python main.py
如果你更喜欢经典工作流,可以自己激活 venv。项目和其入口点会被安装进 .venv,因此环境激活后同样可以用名称运行:
source
.venv/bin/activate
my-project
两种方式都可行,但 uv run 的优势在于每次调用都会让环境与 uv.lock 保持同步。
同步与复现环境
当你克隆一个使用 uv 的项目时,运行 uv sync 以安装 uv.lock 中精确锁定的版本:
uv sync
Resolved 12 packages in 5ms
Installed 12 packages in 110ms
uv sync 使用 uv.lock 中为当前平台和 Python 版本记录的版本。锁文件可跨系统移植,但平台标记可能在 Linux、macOS 或 Windows 上选择不同的包。这是要在 CI、Docker 构建以及每次全新检出时运行的命令。
如果 pyproject.toml 发生变动但锁文件已过时,用以下命令刷新锁:
uv lock
使用 uv lock --upgrade 将每个依赖提升到 pyproject.toml 版本约束允许的最新版本;使用 uv lock --upgrade-package requests 只提升单个包。
直接管理虚拟环境
uv 也可作为 virtualenv 的更快替代品。要在当前目录创建一个独立的 venv:
uv venv
Using Python 3.12.8
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
用 --python 指定 Python 版本:
uv venv --python 3.11
指定不同的路径:
uv venv /tmp/myenv
一旦 venv 存在,就可以用 uv pip 作为常规 pip 命令的快速替代品:
uv pip install requests
uv pip install -r requirements.txt
uv pip freeze
uv pip list
uv pip 接口刻意与 pip 兼容,这让现有项目无需重组成基于 pyproject.toml 的项目就能轻松采用 uv。
若要重温经典虚拟环境,请参阅 Python 虚拟环境指南。
安装与管理 Python 版本
uv 可以在不触碰系统 Python 的情况下下载并管理 Python 解释器。列出可用与已安装的版本:
uv python list
安装特定版本:
uv python install 3.12
uv python install 3.11 3.13
下载的解释器位于 ~/.local/share/uv/python/ 下,独立于系统包管理器,因此这里不会干扰 apt 或 dnf 安装的 Python。要把项目绑定到其中一个版本,使用 uv python pin,它会把版本写入 .python-version 文件并打印所做的改动:
uv python pin 3.13
你也可以在创建虚拟环境时传入 --python:
uv venv --python 3.13
uv python install 会把 python3.12 这类带版本的可执行文件放到 ~/.local/bin。如果该目录不在你的 PATH 中,uv 可以帮你添加:
uv python update-shell
不再需要的解释器同样可以轻松移除:
uv python uninstall 3.11
当 uv run 启动项目时,它会读取 .python-version 与 pyproject.toml 中的 requires-python 约束,然后自动选择或下载匹配的解释器。要确认 shell 当前使用的是哪个解释器,请参阅检查 Python 版本的指南。
安装 CLI 工具
uv 内置了一个类似 pipx 的工具管理器。它在隔离环境中安装基于 Python 的 CLI,以免污染你的系统 Python:
uv tool install ruff
ruff 二进制现在已在你的 PATH 中。列出、升级或移除工具:
uv tool list
uv tool upgrade ruff
uv tool uninstall ruff
若要免永久安装地运行一个工具,使用 uvx(即 uv tool run 的别名):
uvx ruff check .
uvx 会把工具下载到缓存环境、运行它,并在后续调用时复用该缓存。这是试用 CLI 而不让它常驻的最快方式。
运行单文件脚本
Python 脚本可以通过 PEP 723 注释块内联声明依赖。uv run 会读取该块,并在执行脚本前搭建一个临时环境:
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests",
# ]
# ///
import
requests
response
=
requests
.
get
(
"https://api.github.com"
)
print
(
response
.
status_code
)
用以下命令运行脚本:
uv run script.py
uv 会创建一个临时 venv,安装 requests,运行脚本,并把该环境缓存起来留待下次使用。这种模式适用于完整项目显得过重的小型工具和一次性自动化。
故障排查
uv: command not found(安装后找不到 uv 命令)——安装程序把二进制放在 ~/.local/bin,它可能不在你的 PATH 中。在 shell 配置文件中加入 export PATH="$HOME/.local/bin:$PATH",然后重新加载 shell。用 which uv 验证。
Installation fails with "error: externally-managed-environment"(安装报 externally-managed-environment 错误)——这条信息来自系统 pip 而非 uv。请改用 pipx install uv 或独立安装脚本。在现代 Ubuntu 和 Debian 发行版上,不建议把 Python 包安装到系统 Python 中。
uv sync 安装的版本与预期不符——请确认 uv.lock 已提交到仓库。没有锁文件时,uv sync 会回退到从 pyproject.toml 解析,可能选到更新的版本。提交 uv.lock 以在多台机器间保持环境可复现。
uv cannot find a suitable Python interpreter(uv 找不到合适的 Python 解释器)——运行 uv python install 3.12(或你的项目所需的版本)让 uv 下载匹配的解释器。pyproject.toml 中的 requires-python 字段告诉 uv 哪些版本可接受。
Permission denied when installing to the system(向系统安装时权限被拒绝)——uv 不需要 root。如果命令提示输入 sudo,说明目标路径不对。请使用项目虚拟环境,或用 uv tool install 安装 CLI,而不是写入系统目录。
常见问题(FAQ)
uv 与 pip 有何不同?pip 把包安装到已有的 Python 环境中。uv 是一个完整的项目管理器:它创建并管理虚拟环境、锁定依赖、安装 Python 解释器,并运行脚本和工具。uv pip 还为只想获得速度、不想采用整套工作流的团队提供了兼容 pip 的替代命令。
uv 会取代 Poetry 或 Hatch 吗?对大多数项目来说会。uv 读取 Poetry 和 Hatch 使用的标准 pyproject.toml 格式,管理锁文件并处理依赖分组。如果你依赖 Poetry 插件或 Hatch 构建钩子的特定功能,迁移前请先评估这些需求。
uv 与现有的 requirements.txt 工作流兼容吗?兼容。uv pip install -r requirements.txt 可作为 pip install -r 的更快替代品;uv pip compile 能从你未锁定的输入生成已锁定的 requirements 文件,类似 pip-tools 的 pip-compile。
我可以在 Docker 中使用 uv 吗?可以,而且很合适。先复制 pyproject.toml 和 uv.lock,运行 uv sync --locked --no-install-project 在独立层安装依赖,然后复制其余源码并运行 uv sync --locked。把 /root/.cache/uv 挂载为构建缓存,可让下载的 wheel 在多次构建间保留。优先使用 --locked 而非 --frozen,因为前者在 uv.lock 与 pyproject.toml 不一致时让构建失败,而不是悄悄安装过期的锁文件。
uv 把下载的解释器和包缓存存放在哪里?解释器位于 ~/.local/share/uv/python/,用 uv tool install 安装的工具位于 ~/.local/share/uv/tools/,包缓存位于 ~/.cache/uv/。三者都遵循 XDG 基础目录规范,因此 XDG_DATA_HOME 和 XDG_CACHE_HOME 会一并移动它们。若想单独移动其中一个而不影响其余,可设置 UV_PYTHON_INSTALL_DIR、UV_TOOL_DIR 或 UV_CACHE_DIR。
结论
uv 把以前需要 pip、virtualenv、pip-tools、pipx 和 pyenv 才能完成的工作整合进一个快速的二进制文件。速度是最显眼的特性,但真正的收益是为项目、工具、脚本和 Python 版本提供了一套统一、一致的工作流。
关于 Linux 上相关的 Python 工具,请参阅 Ubuntu 26.04 安装 Python 指南和 Python 虚拟环境指南。