做 Python 开发久了,大概率都遇到过这些问题:
系统里同时装了 Python 3.10、3.11、3.12,不知道项目到底用了哪个;
pip install 装着装着,环境依赖开始互相打架;
venv 创建了一堆,却忘了哪个项目对应哪个环境;
换一台电脑后,requirements.txt 又装不出原来的环境;
pyenv + venv + pip + pip-tools 功能没问题,但工具链越来越长。
这几年 Python 生态中出现了一个很值得关注的工具——uv uv 由 Astral 开发,目标不是单纯替代 pip,而是将 Python 版本管理、虚拟环境、依赖管理、项目运行和锁文件管理整合到一个工具中。 简单理解就是:
pyenv + venv + pip + pip-tools
↓
uv对于日常 Python 项目来说,一套 uv 基本就能把环境管理问题包圆。
一、uv 到底是什么?
uv 是一个 Python 包和项目管理工具。 它既可以管理 Python 解释器,也可以创建虚拟环境,还能完成:
Python 版本管理
虚拟环境管理
依赖安装
依赖锁定
项目初始化
项目运行
工具运行
requirements.txt 兼容官方目前提供了包括 uv python、uv venv、uv add、uv sync、uv run 等完整命令体系。 这意味着以前可能需要:
pyenv
python -m venv
pip
pip-tools现在很多项目只需要:
uv二、安装 uv
uv 本身并不依赖 Python,所以即使电脑还没有配置好 Python,也可以先安装 uv,再让 uv 帮我们安装 Python。
macOS / Linux
可以使用官方安装脚本:
curl -LsSf https://astral.sh/uv/install.sh | sh安装完成后检查:
uv --version如果终端提示找不到 uv,重新打开 Terminal,或者检查 uv 的安装目录是否已经加入 PATH。
Windows
Windows PowerShell 可以使用:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"然后执行:
uv --version能够正常输出版本号,就说明安装完成。
三、使用 uv 安装 Python
这是 uv 非常方便的一点: Python 本身也可以交给 uv 管理。 查看可用的 Python:
uv python list安装 Python 3.12:
uv python install 3.12也可以安装指定版本:
uv python install 3.12.11如果不指定版本:
uv python installuv 会安装默认推荐的 Python 版本。 官方文档说明,如果系统已经安装 Python,uv 可以自动发现并使用;如果需要的 Python 不存在,uv 也可以下载安装对应版本。 查看 uv 找到的 Python:
uv python find例如:
uv python find 3.12还可以查看 uv 管理 Python 的安装目录:
uv python dir四、给项目固定 Python 版本
假设我们的项目要求使用 Python 3.12。 进入项目:
cd my-project执行:
uv python pin 3.12此时项目目录通常会出现:
.python-version内容类似:
3.12以后 uv 在这个项目中工作时,就会优先使用对应的 Python。这个功能非常适合团队协作。 例如:
项目 A → Python 3.10
项目 B → Python 3.12
项目 C → Python 3.13不用频繁修改系统 Python。
五、创建 Python 虚拟环境
如果只是想把 uv 当成一个更方便的 venv + pip 使用,可以直接执行:
uv venv
# 默认会创建:.venv/
# 如果指定 Python 版本:
uv venv --python 3.12
项目结构变成:
my-project/
├── .venv/
└── ...uv 官方也推荐使用虚拟环境,而不是直接往系统 Python 中安装项目依赖。
六、激活虚拟环境
uv 创建的 .venv 本质上仍然是标准 Python Virtual Environment,所以传统的激活方式依旧有效。
macOS / Linux
source .venv/bin/activate
# 终端通常会出现:(.venv) user@MacBook my-project %
# 退出:
deactivate
Windows PowerShell
.venv\Scripts\Activate.ps1CMD:
.venv\Scripts\activate.bat不过使用 uv 后,其实很多时候不需要手动 activate。 后面会讲到一个非常实用的命令:
uv run七、使用 uv 安装 Python 包
如果你习惯 pip 风格,可以直接使用:
uv pip install requests
# 安装多个:
uv pip install requests pandas numpy
# 安装指定版本:
uv pip install "pandas==2.3.2"
# 查看:
uv pip list
# 卸载:
uv pip uninstall pandas
# 如果项目已有:requirements.txt
# 依然可以:
uv pip install -r requirements.txt因此从 pip 迁移到 uv 的成本并不高。
八、更推荐的方式:使用 uv 项目模式
真正发挥 uv 优势的方式,并不是一直使用:
uv pip install而是使用 uv 的 Project 工作流。
# 创建项目:
uv init my-project
# 进入项目:
cd my-project通常会得到类似结构:
my-project/
├── .gitignore
├── .python-version
├── README.md
├── main.py
└── pyproject.toml其中最重要的是:
pyproject.tomlPython 项目的依赖和元数据会统一放在这里。
九、使用 uv add 管理依赖
# 比如项目需要 Requests:
uv add requests
# 需要 FastAPI:
uv add fastapi
# 再安装 Uvicorn:
uv add uvicorn此时:
pyproject.toml会自动更新。 例如:
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.116.0",
"requests>=2.32.0",
"uvicorn>=0.35.0",
]同时项目中会生成:
uv.lock因此 uv.lock 应当提交 Git,用来保证不同机器安装出的项目环境尽可能一致。
十、开发依赖怎么安装?
例如我们需要:
pytest
ruff这些东西只用于开发,不属于程序运行时依赖。
# 可以执行:
uv add --dev pytest
uv add --dev ruff这样就可以把生产依赖和开发依赖区分开。 比如:
生产:
fastapi
sqlalchemy
pydantic
开发:
pytest
ruff
mypy项目结构会清晰很多。
十一、uv sync:一条命令恢复项目环境
这是 uv 很舒服的地方。 假设你从 GitHub 克隆一个项目:
git clone xxx
cd project项目里面已经有:
pyproject.toml
uv.lock以前可能需要:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt现在直接:
uv syncuv 会按照项目配置和锁文件创建或同步 .venv。 官方说明,uv sync 会把锁文件中的依赖同步到项目环境;默认情况下还会进行 exact sync,也就是清理由锁文件之外的额外包。 因此对于团队项目,我通常建议:
pyproject.toml
uv.lock
.python-version都交给 Git 管理。而:
.venv/不要提交。
十二、不激活环境,直接使用 uv run
# 传统 Python 工作流通常是:
source .venv/bin/activate
python main.py
# 使用 uv 后可以直接:
uv run python main.py
# 甚至:
uv run main.py
# 运行 FastAPI:
uv run uvicorn main:app --reload
# 运行 pytest:
uv run pytest
# 运行 Ruff:
uv run ruff check .比单纯依赖“我有没有正确激活那个环境”更加可靠。
十三、一个完整 FastAPI 项目示例
下面实际创建一个项目。
1. 创建项目
uv init uv-fastapi-demo
# 进入目录:
cd uv-fastapi-demo2. 指定 Python
uv python pin 3.123. 添加依赖
uv add fastapi uvicorn4. 编写 main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def index():
return {
"message": "Hello uv"
}5. 启动
uv run uvicorn main:app --reload
# 整个过程中,我们甚至没有执行:
source .venv/bin/activate环境依然能够正常工作。
十四、已有 requirements.txt 怎么迁移?
很多老项目的结构是:
project/
├── main.py
└── requirements.txtrequirements.txt:
fastapi
uvicorn
requests
sqlalchemy如果暂时不想迁移项目结构,可以直接:
uv venv
# 然后:
uv pip install -r requirements.txt这是最简单的迁移方法。 如果准备彻底切换到 uv Project,则建议逐渐转向:
pyproject.toml
+
uv.lock官方目前也提供了从 pip 项目迁移到 uv Project 的专门指南。
十五、临时运行工具:uvx
uv 还有一个非常实用的功能:
uvx
# 例如你只是临时使用 Ruff:
uvx ruff check .
# 不用先:
pip install ruff
# 也不用污染当前项目环境。再比如:
uvx black .这种工具尤其适合:
ruff
black
cookiecutter
httpie
pre-commit等 CLI 应用。 简单理解:
uv add十六、临时给脚本添加依赖
还有一个很方便的场景。比如:
import requests
print(requests.get("https://example.com").status_code)只是临时执行,又不想创建完整项目。 可以:
uv run --with requests test.pyuv 会为这次运行准备对应依赖,而不需要手动维护一个长期虚拟环境。官方也支持在 Python 脚本内通过标准 inline metadata 声明依赖。 这对于:
数据处理脚本
运维脚本
临时爬虫
自动化脚本
Demo特别方便。
十七、推荐的项目目录
对于新的 Python 后端或 AI 项目,我比较推荐:
my-project/
├── .git/
├── .gitignore
├── .python-version
├── .venv/
├── pyproject.toml
├── uv.lock
├── README.md
├── src/
│ └── app/
│ ├── __init__.py
│ └── main.py
└── tests/
└── test_main.py其中:
.python-version
负责 Python 版本。
pyproject.toml
负责项目配置和依赖声明。
uv.lock
负责锁定最终依赖版本。
.venv负责真正运行的 Python 环境。这一套职责分工非常清晰。
十八、几个容易踩的坑
1. 不要把 .venv 提交 Git
虚拟环境包含大量平台相关文件。应该提交:
pyproject.toml
uv.lock
.python-version
而不是:
.venv/2. 项目依赖优先用 uv add
# 例如:
uv add pandas
# 而不是在 uv Project 中长期依赖:
uv pip install pandas因为前者会同时维护:
pyproject.toml
uv.lock
.venv后者更接近传统 pip 工作流。 官方也明确建议项目依赖使用 uv add,而不是手动修改 uv 管理的项目环境。
3. 不一定需要 activate
这是从传统 venv 切到 uv 后最需要改变的习惯之一。与其:
source .venv/bin/activate
python main.py
# 很多时候更推荐:
uv run python main.py这样可以减少“终端激活了错误环境”的问题。
4. CI/CD 中优先依赖锁文件
# 例如服务器或者 CI 中:
uv sync --locked
# 然后:
uv run pytest--locked 可以要求现有锁文件必须与项目配置一致,否则直接报错,而不是悄悄修改 lockfile。官方 GitHub Actions 示例也采用了 uv sync 配合锁文件进行环境安装。
十九、uv、pip 和 Conda 怎么选?
它们其实不是完全相同定位。如果项目主要是:
Web 后端
FastAPI
Flask
Django
Python CLI
普通数据分析
自动化脚本
Agent
LLM 应用如果是:
CUDA
复杂科学计算
Conda-forge
大量非 Python 二进制依赖Conda / Mamba 依旧有自己的优势。而对于纯 Python 项目,uv 最大的价值不是简单的“pip 更快”,而是:
Python
+
虚拟环境
+
依赖
+
锁文件
+
项目运行终于可以用一套统一的工作流进行管理。
