uv 系列(一):全景与安装——统一现代 Python 工具链
核心目标:理解 uv 解决的问题和能力边界,在 Windows、macOS 或 Linux 上正确安装 uv,并用它发现、安装、固定和选择 Python 解释器。
前置知识:会在终端执行命令,了解 Python 包和虚拟环境的基本概念即可。
验证环境:uv 0.11.29、Windows 11 PowerShell;文中的跨平台命令同时依据 uv 官方文档复核。最后复核日期:2026-07-20。
1.1 为什么 Python 项目总有一长串“准备工作”
一个传统 Python 项目的启动说明经常是这样的:先安装合适版本的 Python,再创建虚拟环境,激活环境,升级 pip,安装 requirements,最后才能运行程序。工具本身都没有错,真正的问题是职责分散:
| 需求 | 传统常见工具 | 容易出现的问题 |
|---|---|---|
| 安装 Python | 系统安装器、pyenv | 团队成员版本不一致 |
| 创建虚拟环境 | venv、virtualenv |
环境位置和激活方式不统一 |
| 安装依赖 | pip | 安装结果受时间和平台影响 |
| 锁定依赖 | pip-tools 等 | 输入文件、输出文件和环境容易漂移 |
| 运行 CLI 工具 | pipx | 又多一套环境和升级命令 |
| 构建与上传 | build、twine | 发布链路分散,配置重复 |
uv 的价值不是“把 pip 写得更快”这么简单,而是提供一套连贯工作流:
这条链路最重要的收益是:项目元数据、锁定结果和实际环境能够被同一工具持续校验。
1.2 uv 是什么,不是什么
uv 是 Astral 团队使用 Rust 编写的 Python 包与项目管理工具。它覆盖以下能力:
- 安装和选择 CPython、PyPy 等 Python 实现;
- 创建和维护项目虚拟环境;
- 解析、锁定、安装和升级依赖;
- 运行项目命令、单文件脚本和临时 CLI 工具;
- 构建 sdist/wheel 并发布到包索引;
- 管理多包 workspace;
- 提供面向旧工作流的
uv pip兼容接口。
但需要守住三个边界。
1.2.1 uv 不等于 pip
uv pip install 的命令外观类似 pip,但 uv 不会调用 pip。它有自己的解析器、安装器和缓存,因此在严格性、解析策略和边界行为上可能不同。
新项目应优先采用项目接口:
uv init
uv add httpx
uv run python main.py
已有项目若暂时只能使用 requirements 工作流,可先采用兼容接口:
uv venv
uv pip sync requirements.txt
1.2.2 uv 不替代所有质量工具
uv 负责“提供环境并运行工具”,不会替代 Ruff、pytest、Mypy 等工具本身:
uv run ruff check .
uv run pytest
uv run mypy src
1.2.3 uv 不是通用系统包管理器
uv 处理 Python 解释器和 Python 包,但不会像 apt、Homebrew 或 Conda 那样完整管理 CUDA、数据库客户端、编译器等系统依赖。带有复杂非 Python 依赖的项目,仍需把系统层和 Python 层分开治理。
1.3 安装 uv
1.3.1 Windows
官方独立安装器:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
也可以使用 WinGet:
winget install --id=astral-sh.uv -e
独立安装器适合希望直接使用 uv 自更新能力的场景;WinGet 适合统一由系统包管理器维护的软件清单。不要混用多种安装来源,否则 PATH 中可能同时存在多个 uv.exe。
安全提示:管道执行网络脚本前,可以先运行
irm https://astral.sh/uv/install.ps1阅读内容。受管环境中应固定版本并按组织的软件供应链流程校验来源。
1.3.2 macOS 与 Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
或者:
brew install uv
如果没有 curl,可以使用 wget -qO- ... | sh。生产构建环境建议固定 uv 版本,而不是永远下载“latest”:
curl -LsSf https://astral.sh/uv/0.11.29/install.sh | sh
这里的版本号只是本文验证值,实际项目应通过自动化依赖更新流程定期升级。
1.3.3 通过 PyPI 安装
pipx install uv
也可以 pip install uv,但官方建议将 uv 安装到隔离环境。这个方式依赖已有 Python,更适合受限环境或暂时评估;uv 的独立安装器不要求预先准备 Python。
1.3.4 验证安装来源
uv --version
Get-Command uv
uv --version
command -v uv
预期看到版本和唯一的可执行文件路径。如果升级后版本没有变化,优先检查 PATH 中是否有旧副本,而不是反复重装。
1.4 升级、补全与卸载
独立安装器安装的 uv 可以自更新:
uv self update
由 WinGet、Homebrew、pipx 等安装时,应使用对应包管理器升级;此时 uv self update 通常被禁用。
查看 PowerShell 补全脚本:
uv generate-shell-completion powershell
要永久启用,可按官方安装页提供的方式把生成命令加入 $PROFILE。修改 shell 配置属于用户级行为,团队脚本不应未经说明自动执行。
卸载前先查看 uv 管理的数据位置:
uv cache dir
uv python dir
uv tool dir
删除 uv 二进制并不会自动删除缓存、托管 Python 和工具环境。是否清理这些数据应由用户明确决定。
1.5 uv 如何理解 Python
uv 把 Python 分为两类:
- managed Python:由 uv 下载和维护;
- system Python:不是由 uv 安装的解释器,包括系统安装器、pyenv 或其他工具管理的 Python。
“system”并不等同于操作系统自带,只表示不归 uv 管理。uv 可以发现并使用两类解释器。
1.5.1 查看可用解释器
uv python list
uv python list 3.12
uv python find 3.12
list 同时展示已安装和可下载版本;find 返回满足请求的具体解释器。脚本若需要机器可读路径,可使用 find,不要解析人类可读的列表文本。
1.5.2 安装 Python
uv python install 3.12
uv python install 3.11 3.12 3.13
uv python install pypy@3.10
只写 3.12 表示选择 uv 当前支持的最新 3.12 补丁版本。需要完全一致的解释器时可以写完整版本,但普通项目通常应允许安全的补丁升级。
uv 的可下载 Python 清单随 uv 版本发布而冻结。如果某个刚发布的 Python 版本不可见,先升级 uv,再排查网络。
1.5.3 自动下载
很多命令在找不到匹配解释器时会自动下载:
uv venv --python 3.12
在离线或严格受管环境中,可以关闭此行为:
uv --no-python-downloads venv --python 3.12
关闭后找不到解释器会直接失败。这是可控性提升,不是故障。
1.5.4 固定项目默认版本
uv python pin 3.12
Get-Content .python-version
.python-version 表达开发者进入项目时的默认版本请求;pyproject.toml 中的 requires-python 表达项目支持范围。两者不能混为一谈:
[project]
requires-python = ">=3.11"
# .python-version
3.12
这表示项目承诺支持 3.11 及以上,而本地默认用 3.12 开发。库项目应在 CI 中实际测试最低版本和当前稳定版本,不能只靠声明。
1.5.5 解释器选择顺序
可以把选择过程理解为:
真实发现过程还受配置和环境变量影响,但排障时按这个顺序检查通常最快。
1.6 虚拟环境与 uv run
1.6.1 显式创建环境
mkdir hello-uv
Set-Location hello-uv
uv venv --python 3.12
默认创建 .venv。激活方式:
.\.venv\Scripts\Activate.ps1
python --version
source .venv/bin/activate
python --version
不要提交 .venv。虚拟环境含绝对路径和平台相关二进制,不具备可移植性;应提交项目声明和锁文件,在目标机器重建。
1.6.2 为什么通常不必激活
在 uv 项目中:
uv run python -c "import sys; print(sys.executable)"
uv run 会确保项目环境存在并与锁文件同步,然后在该环境中执行命令。手工激活适合 IDE、交互式调试或需要连续执行很多原生命令的场景;自动化脚本和文档示例优先写 uv run,环境来源更明确。
1.7 最小实验:证明选择的是哪个 Python
创建 show_runtime.py:
from __future__ import annotations
import platform
import sys
def main() -> None:
print(f"executable={sys.executable}")
print(f"version={platform.python_version()}")
print(f"implementation={platform.python_implementation()}")
print(f"platform={platform.platform()}")
if __name__ == "__main__":
main()
分别运行:
uv run --no-project --python 3.11 show_runtime.py
uv run --no-project --python 3.12 show_runtime.py
--no-project 表示不要向上查找并加载某个 pyproject.toml;这样实验结果只由显式 Python 请求决定。如果第二个版本尚未安装,且未禁止下载,uv 会自动准备它。
验收:
- 两次输出的
executable指向不同解释器; - 版本分别满足 3.11 和 3.12;
- 当前 shell 无须激活任何虚拟环境;
- 删除临时执行环境不会影响系统 Python。
1.8 常见误区与排障
误区一:安装 uv 后 python 就一定指向 uv 的 Python
默认情况下,uv python install 3.12主要提供带版本的可执行文件,并不会无条件覆盖现有 python。应通过 uv run --python 3.12 ... 或项目配置明确选择。
误区二:.python-version 就是项目兼容范围
它只是默认版本请求。真正发布给其他工具和包索引的兼容范围是 requires-python。
误区三:虚拟环境应该提交 Git
应提交 pyproject.toml 和 uv.lock,环境在每台机器重新同步。
找不到 uv
Get-Command uv -All
$env:PATH -split ';'
重新打开终端,确认安装目录进入 PATH。若有多个结果,删除或调整旧版本路径。
找不到 Python
uv python list 3.12
uv python find 3.12
uv python install 3.12
如果组织禁止下载,确认目标 Python 已预装,并用完整路径测试:
uv run --python C:\Python312\python.exe --no-project python -V
1.9 最佳实践清单
- 团队记录并固定 CI 使用的 uv 版本。
- 安装来源只有一个,
PATH中不存在多个 uv。 - 项目用
requires-python声明兼容范围。 - 用
.python-version表达本地默认版本,不冒充兼容性测试。 - 自动化命令优先使用
uv run,减少对 shell 激活状态的依赖。 -
.venv不进入版本控制。 - 预发布或实验性 Python 变体不作为默认生产基线。
- 受管环境明确配置是否允许自动下载 Python。
1.10 本篇小结
uv 把 Python 解释器、项目环境、依赖和运行命令连接成一条可验证链路。完成本篇后,最重要的不是记住所有命令,而是能回答三个问题:当前使用哪个 uv、当前命令使用哪个 Python、这个选择来自显式参数还是项目配置。
下一篇将创建可发布的 weather-cli,深入理解 pyproject.toml、src/ 布局、构建系统和命令入口。
官方参考
更多推荐



所有评论(0)