UV 包管理器 - 新一代的 Python 包和环境管理神器
1. uv 介绍
1.1 uv 是什么?
简介:
-
用 Rust 编写的极其快速的
Python 包管理器 -
能替代 pip、pip-tools、pipx、poetry、pyenv、twine、virtualenv 等多种工具
-
比 pip 快 10 到 100 倍
uv 是由 Astral 开发的高性能 Python 工具,旨在用一个工具替代上述绝大多数工具
涵盖了从Python 版本管理到包管理,再到虚拟环境和发布的全流程。
1.2 uv 能做什么?
安装和管理 python 版本,创建项目,快速安装包,创建虚拟环境,项目打包/构建和发布
通过 uv.lock 和 pyproject.toml 文件安装依赖复刻项目
无需手动下载管理复杂的 python 环境,节省我们的精力与时间
1.3 为什么用 uv?
python 发展前期,由于官方对于环境和依赖包的管理不够重视,导致后面出现一大堆工具,极其繁杂!堪比秦始皇统一六国前的各国文字以及丈量工具皆不相同
学习 python 技术栈的过程中,了解到目前主流的 python 环境管理方式 主要有以下几种:
1. venv + pip
python 原生的管理方式,极不灵活,版本依赖不明确, 缺乏统一的锁文件机制
2. conda, mamba
功能强大但依赖大,速度慢,存在收到律师函的风险
Anaconda 商业版在 200 人以上企业需要付费授权,Miniconda / Micromamba 完全免费
3. uv
安装方便,无需单独使用 pip、pip-tools、pipx、poetry、pyenv、twine、virtualenv 等多种工具,全部都整合到了 uv 中,能大大简化开发流程
统一的锁文件给整个项目做依赖管理
全局缓存,节省空间
相比于 conda 的臃肿,uv 显得更加轻量级,所以我选择`使用 uv 来安装和管理 python 版本`
注意:
macOS and Linux 与 windows 的安装和运行命令不同,详情见官网文档,本文使用 windows 做演示
如果使用 uv 的话不建议再用传统的 pip 工具,避免污染环境
tip:uv 于 python,类似于前端的 npm/pnpm + nvm + cli/Vite
1.4 命令对照表
Python 和 Node.js 生态对照表(便于前端同学理解)
| Python 生态 | Node.js 生态 | 说明 |
|---|---|---|
| Python | Node.js | 运行时 |
| uv | pnpm + nvm + Vite(三合一) | 最核心类比:uv = pnpm(依赖管理) + nvm(版本管理) + Vite(构建) |
| PyPI | npm registry | 官方包仓库 |
| uv python pin | nvm use | 固定项目使用特定版本 |
| uv add | pnpm add | 添加依赖并写入配置文件(pyproject.toml / package.json) |
| uv sync | pnpm install | 安装所有依赖(最常用!) |
| uv run | pnpm run / npx | 在项目环境中运行命令 |
| uv build | npm pack / pnpm pack | 打包成可分发的包(.whl / .tgz) |
| uv publish | npm publish / pnpm publish | 发布到 PyPI / npm registry |
| .venv | node_modules | 本地依赖文件夹(虚拟环境 vs 依赖目录) |
| uv.lock | pnpm-lock.yaml(推荐) / package-lock.json | 精确锁定版本文件 |
| uv tool install | pnpm dlx / npx | 临时安装一次性工具(类似 pipx) |
| uv python install | nvm install | 下载指定 Python 版本 |
Python 传统命令 vs uv 命令完整对照表
| 传统 Python 命令 | uv 命令 | 说明 |
|---|---|---|
pyenv global 3.12 |
uv python pin 3.12 |
切换/固定 Python 版本 |
pyenv install 3.12 |
uv python install 3.12 |
下载指定 Python |
python -m venv .venv |
uv venv |
创建虚拟环境 |
source .venv/bin/activate |
无需激活,直接 uv run
|
激活虚拟环境 |
pip install -r requirements.txt |
uv sync |
安装依赖(项目级) |
pip install fastapi |
uv add fastapi |
添加单个依赖 |
pip install "fastapi[standard]" |
uv add "fastapi[standard]" |
添加带 extras |
pip install -r requirements-dev.txt |
uv add --dev pytest |
添加开发依赖 |
pip install fastapi(在激活环境下) |
uv pip install fastapi |
临时安装(不写进项目) |
python main.py(需先激活) |
uv run python main.py |
运行脚本 |
uvicorn main:app(需激活) |
uv run uvicorn main:app |
运行 uvicorn |
pytest |
uv run pytest |
运行测试 |
python -m build |
uv build |
打包 |
twine upload dist/* |
uv publish |
发布到 PyPI |
pipx install httpie |
uv tool install httpie |
安装一次性工具 |
pipdeptree |
uv tree |
查看依赖树 |
手动 pip uninstall
|
uv sync --prune |
清理多余包 |
rm -rf .venv |
rm -rf .venv(直接删除即可) |
删除虚拟环境 |
2. uv 安装
uv 安装的时候需要挂梯子,请放心大胆的用,全程花不了多少 MB 的流量
Windows 安装命令
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
uv 会默认安装到 C:\Users\dcry\.local\bin 目录下
提示安装成功,请重新启动您的终端
如果不重启终端直接运行话会报错,提示命令不可运行
查看 uv 包版本,验证是否安装成功
uv self version
也可用 uv --version 和 uv -V 查看 uv 版本,网上有的教程说是 uv version 命令查看版本,简直乱写,误人子弟!
查看菜单列表,列出可用的命令
uv
能正常显示命令列表也说明 uv 安装成功
3. 安装/切换 Python
使用 uv 后就不需要从官网下载安装 python 包了,但是可以在官网查看全部的 python 版本号
python 官网:www.python.org/downloads/
查看已安装和可用的 Python 版本
uv python list
好家伙,不知道是安装 uv 的时候还是运行这个命令的时候,竟然自动给我安装了 3.13.3 的 python 版本
那我就无需重复安装 python 了,就用它自带的这个版本吧
不过还是说说如何下载指定版本的 python
下载 3.14.2 的 python 版本
uv python install 3.14.2
然后再次运行命令查看是否安装成功
uv python list
显示 uv 安装的 Python 版本路径
uv python dir
卸载 3.14.2 的 python 版本
uv python uninstall 3.14.2
切换当前项目的 python 版本
uv python pin 3.14.2
注意:如果是在项目中运行 pin 命令,切换版本后记得运行 uv sync 命令同步环境(自动下载 python + 创建 .venv + 安装依赖),如果还没创建项目就无需运行 uv sync,后面的流程中 uv 会自动帮你创建环境。
注意:本地 pin 优先级高于全局 pin
切换全局默认 python 版本(电脑上所有新项目默认都用 3.14.2)
uv python pin 3.14.2 --global
注意:全局默认 python 版本,只有当项目中没有本地 .python-version 时才生效
查看当前使用的是哪个 Python 版本
uv run python --version
4. 用 uv 新建项目
新建一个项目文件夹,命名为“uv-demo”,进入文件夹,打开 Git Bash(cmd 或者 PowerShell 也行,都差不多)
运行命令初始化项目
uv init
uv 生成了下面四个文件
├── main.py
└── pyproject.toml
├── .python-version
├── README.md
简单解释这四个文件的作用
-
main.py
main.py 是程序的入口文件
-
pyproject.toml
pyproject.toml 是整个项目的配置文件
包含:项目名称(name)、项目版本(version)、项目描述(description),说明文档(readme),Python 版本要求(requires-python),依赖列表(dependencies)
-
python-version
python-version 文件用于指定当前项目使用的 Python 版本
在当前项目内运行 uv run、uv add、uv sync、uv build 等 uv 命令就会自动使用此版本
如果想切换当前项目的 python 版本需要运行
uv python pin 3.14.2命令python-version 文件只影响当前项目(不会影响其他项目)
-
README.md
项目说明文档,这个不需要多解释了吧
5. 运行 python 项目/主程序
打开 main.py 文件,发现有默认代码,内容为输出打印
运行 main.py 程序
uv run main.py
vscode 提示命令不可运行,把所有 vscode 窗口关闭重新打开即可
再次运行命令,可以在控制台看见输出 Hello from uv-demo!
6. 用 uv 创建虚拟环境
6.1 什么是虚拟环境?
因为不同的 python 项目所需的环境依赖版本不同,如果所有项目都在全局环境中运行,切换不同项目的时候极易发生冲突
所以需要虚拟环境来隔离项目,虚拟环境就是一个用于隔离不同项目的环境
想要将项目发给别人运行的话,只需要将虚拟环境的配置发给对方,对方运行命令安装依赖后即可运行
6.2 怎么创建虚拟环境
前面的 uv run main.py 运行程序后,除了控制台输出打印外,还有一个重点不知道大家有没有观察到
项目下自动生成了 .venv 文件夹 !和 uv.lock 锁文件
-
.venv.venv 文件夹就是虚拟环境,每一个虚拟环境都是完全独立的,一个与系统其他部分隔离的 Python 环境。类似于前端的
package.json和node_modules -
uv.lockuv.lock 是一个跨平台的锁文件(lockfile),包含你项目依赖的准确信息(安装的具体依赖版本)
锁文件会自动从项目依赖中解析出完整的依赖结构和每个库的具体版本并且锁定
锁文件确保开发者使用一致的包版本,运行
uv sync和uv run命令时会自动创建和更新 uv.locktip: 锁文件应被提交到 git 版本控制中,以便实现跨机器的一致且可重复的安装。
几乎所有的教程都在告诉你要先使用 uv 创建虚拟环境,这些博主又在误人子弟
你完全不需要手动创建虚拟环境。在合适的时机,它会静默地自动创建虚拟环境,uv 真的好体贴!!
6.3 什么是合适的时机?
uv 创建虚拟环境非常智能,可以通过运行 uv venv 命令手动创建,它也会根据情况自动创建。
当您首次运行项目命令(即 uv run、uv sync 或 uv lock)或者 uv add xxx 安装库时
uv 将自动在项目的根目录中创建一个 .venv 虚拟环境文件夹(用于隔离依赖安装)和 uv.lock 锁文件(用于记录精确依赖版本,确保可重现性)
来自:docs.astral.sh/uv/guides/p…
7. 用 uv 安装库/依赖包
7.1 安装库
官网:pypi.org/
简介:PyPI 是 Python 的官方第三方软件包仓库,类似 npm
uv 中通过 uv add 命令为项目安装依赖包,安装成功的库名,会存在 pyproject.toml 文件的 dependencies 数组里面,同时也会更新锁定文件和项目环境
安装 numpy 库
uv add numpy
此时,uv 会按顺序执行以下操作:
更新 pyproject.toml:将 numpy 包名和版本范围添加到 [project.dependencies] 列表中。
更新 uv.lock:解析所有依赖项的精确版本和哈希值,确保环境可复现。
同步虚拟环境:直接在 .venv 中安装 numpy 包,让你的代码立刻能跑。
安装特定版本的库
uv add numpy==2.2.5
如果同时安装多个库,中间用逗号隔开
uv add numpy,pandas
删除库
uv remove numpy
tip: uv add 等同于 python 的原生工具 pip 的下载命令 pip install
tip: uv remove 等同于 python 的原生工具 pip 的卸载命令 pip uninstall
tip: 以后在 pypi 安装包的时候,直接把文档安装命令中的 pip install 或者 uv pip install 替换为 uv add 即可。其他人拉取仓库的代码后,只需要运行 uv sync 命令,就能获得一个和你一模一样的开发环境了!
更新库
uv sync --upgrade-package langgraph
7.2 修改库的镜像源为国内地址
文档:docs.astral.sh/uv/concepts…
uv 会默认从 https://pypi.org/ 下载库,在国内的朋友如果没有梯子可能会无法下载
所以 uv 支持通过修改项目下 pyproject.toml 文件的软件包索引(Package indexes),来切换库的国内镜像源
-
单个镜像源
切换为阿里云镜像源
[[tool.uv.index]] name = "aliyun" url = "https://mirrors.aliyun.com/pypi/simple/" default = true默认情况下,uv 将 Python 软件包索引 (PyPI) 作为“默认”索引,即在任何其他索引上都找不到软件包时使用的索引
我这里加上
default = true表示将阿里云镜像源作为“默认”索引 -
多个镜像源
也可以设置多个源,uv 会自动按照顺序决定优先级
以下分别是阿里云镜像源,华为云镜像源和清华大学镜像源
[[tool.uv.index]] name = "aliyun" url = "https://mirrors.aliyun.com/pypi/simple/" [[tool.uv.index]] name = "huaweicloud" url = "https://mirrors.huaweicloud.com/repository/pypi/simple/" [[tool.uv.index]] name = "tuna" url = "https://pypi.tuna.tsinghua.edu.cn/simple/"
注意: uv 只有下载 python 包可以用国内镜像,但是下载 uv 以及 python 版本没办法换国内源;并且听说修改镜像源后速度也不稳定,我没有自己尝试过,因为我挂梯子下载挺好用的
8. uv 的全局缓存
查看项目依赖关系树
uv tree
查看 uv 的全局缓存目录
uv cache dir
当其他项目安装相同的版本库的时候,uv 会复用这些缓存文件,而不是每次都重新下载
uv 下载的包会放在缓存里面,.venv 文件夹里面实际是一些快捷方式,指向你下载过的缓存,所以不会重复下载包;每新建一个虚拟环境都会从快捷方式指向缓存,conda 却是每一次都下载
9. 用 uv 复刻环境/安装项目所需的依赖文件
安装依赖,复刻环境
uv sync
运行命令后,会发生什么?
-
uv 会确认 Python 版本
uv 会根据 .python-version 文件确定应该使用哪个版本的 Python 解释器,如果发现本地没有安装 .python-version 指定的版本,uv 会自动从其托管的二进制库中下载对应的 Python 版本。
-
uv 会对比 pyproject.toml 和 uv.lock 文件
如果 uv.lock 不存在:uv 会根据 pyproject.toml 的要求,解析出满足所有约束的最高版本,并生成 uv.lock
如果 pyproject.toml 有改动:uv 会更新 uv.lock,确保锁定文件与你的最新要求同步。
-
uv 会检查项目根目录下的 .venv 文件夹
如果文件夹不存在,uv 会自动创建一个全新的虚拟环境
如果当前环境的 Python 版本不对,或者包的版本不对,uv 会对其进行调整
删除 .venv 中所有的依赖文件
Remove-Item -Recurse -Fouce .\.venv
也可以直接删除 .venv 文件夹
除了 uv sync 命令,也可以用 uv 从传统的 requirements.txt 文件下载依赖(不建议!)
uv add -r requirements.txt
导出锁文件为 requirements
uv export --format requirements.txt
requirements.txt 格式是 Python 依赖中最广泛支持的格式。它可以与 pip 及其他 Python 包管理器一起使用。
注意:如果用 uv 的话,就别再使用 requirements 了;这里介绍 requirements.txt 是为了给 pip 及其他 Python 包管理器使用。
10. uv 打包和发布包
与前端的打包发包概念不同,这里用 vue 举例,运行 npm run build 之后,生成 dist 文件,本质是:静态 HTML + JS + CSS 文件,所以可以直接丢给 Nginx 部署就能进行访问
在 Python 中,打包是将程序生成 .whl 和 .tar.gz 文件,发布包是将代码上传到 PyPI(Python Package Index),别人可以通过 pip install 或 uv add 来将它安装到项目中进行使用(也可以将 .whl 和 .tar.gz 文件 直接发给对方进行安装使用)
既然项目打包成 .whl 和 .tar.gz 文件是给别的程序员使用,那我如果想将写好的 python 程序提供给普通用户使用应该怎么做呢?要么直接打包成 exe 程序,要么通过 Docker 部署到服务器运行,通过浏览器进行访问
10.1 打包
uv build
执行后会在项目根目录生成 dist/ 文件夹,里面有两个文件,都是可分发的安装包
-
.whl
Python Wheel(二进制分发包)
已经预编译好的二进制文件
安装速度极快(秒级)
文件大小通常更小
-
.tar.gz
Source Distribution(源码分发包)
纯源码 + 构建脚本
安装速度较慢(需要现场编译)
文件大小通常更大
拿到这两个文件后具体怎么使用?运行命令加到自己的项目依赖里
uv add ./dist/myproject-0.1.0-py3-none-any.whl
这里的 dist 是文件路径,myproject-0.1.0-py3-none-any 是 .whl 文件名
安装后就可以直接 import myproject 使用了
10.2 发布
发布需要 PyPI 账号
运行命令
uv publish
uv 会自动上传 .whl 和 .tar.gz 到 PyPI