Python 虚拟环境是 Python 开发中隔离项目依赖的核心工具。本教程系统讲解从 Python 内置的 venv 到现代化工具 uv 的完整知识体系,帮助读者理解不同工具的设计理念、适用场景和操作方式,最终能够根据项目需求选择最合适的方案。
1. Python 虚拟环境基础
1.1 什么是 venv
venv 是 Python 3.3 及以上版本自带的轻量级虚拟环境管理工具。它的核心作用是为每个项目创建独立的 Python 运行环境,隔离不同项目所需的第三方包版本。
典型场景:项目 A 需要 Django 2.0,项目 B 需要 Django 4.0,如果全局安装会导致依赖冲突,两个项目无法共存。使用 venv 后,每个项目拥有独立的 site-packages 目录,版本冲突自然消除。
我们认为:无论是人还是应用系统,都需要一个干净、集中的工作环境。
1.2 venv 基础操作
创建虚拟环境
在项目根目录下打开终端,运行:
python -m venv .venv
环境名称通常叫 venv 或 .venv(加点为隐藏文件夹)。建议使用 .venv,因为它是很多工具(如 uv、Poetry)的默认目录名,且不会在文件管理器中显得杂乱。
激活虚拟环境
激活后,安装的包才会进入这个独立环境:
| 操作系统 | 命令 |
|---|---|
| Windows (CMD) | .venv\Scripts\activate |
| Windows (PowerShell) | .venv\Scripts\Activate.ps1 |
| macOS / Linux | source .venv/bin/activate |
激活成功后,终端命令行前面会出现 (.venv) 标识。
安装依赖并运行项目
pip install fastapi uvicorn # 安装 fastapi 和 uvicorn 两个依赖
python app.py # 运行项目
退出虚拟环境
deactivate
1.3 管理项目依赖
在虚拟环境中,使用 pip freeze 导出当前环境的所有包及版本:
pip freeze > requirements.txt
其他人拿到项目后,只需运行以下命令即可安装完全相同的依赖版本:
pip install -r requirements.txt
1.4 重要注意事项
不要将虚拟环境提交到 Git 仓库
虚拟环境体积大且包含系统特定文件,不应纳入版本控制。在项目根目录创建 .gitignore 文件,添加以下内容:
.venv/
venv/
有关于
Git 仓库及.gitignore的内容,你可以前往Git的安装与基本使用教程进行回顾。
不同 Python 版本依赖
venv 只使用创建时指定的 Python 解释器版本。如果需要切换 Python 版本,需要删除 .venv 目录后重新创建。
2. Conda 环境管理详解
我们在Python+FastAPI在Windows环境下创建一个基础后端服务教程中介绍了 Conda 的下载、安装、环境管理等操作,你可以前往回顾,这里主要介绍 Conda 与其他环境管理工具的区别和适用场景。
| 特性 | Conda | pip + venv |
|---|---|---|
| 包来源 | Conda 官方仓库(Anaconda.org) | PyPI(Python Package Index) |
| 支持语言 | 跨语言(Python、R等) | 仅 Python |
| 管理 Python 版本 | 可安装/切换不同 Python 版本 | 只使用系统已安装的 Python |
| 管理非 Python 依赖 | 可管理 CUDA、OpenBLAS 等底层库 | 只能通过系统包管理器手动安装 |
| 依赖解析 | 较严格,但可能较慢 | 较宽松 |
| 环境隔离 | 完整隔离(包括系统路径) | Python 级隔离 |
| 预编译包 | 提供预编译二进制(避免编译错误) | 部分包需编译(需系统编译器) |
3. 现代化工具 uv 详解
3.1 什么是 uv
uv 是由 Astral 团队用 Rust 编写的 Python 包和环境管理工具。
uv 的核心优势在于极快的安装速度(比 pip 快 10-100 倍),以及对现有生态的完美兼容(可以直接读取 requirements.txt 和 pyproject.toml)。
3.2 安装 uv
Windows (PowerShell):
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
macOS / Linux:
# 下载最新版本的 uv 安装脚本
curl -LsSf https://astral.sh/uv/install.sh | sh
# 添加到 PATH 环境变量
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
验证安装:
uv --version
3.3 核心工作流
新建项目(推荐方式)
# 初始化项目,自动生成 pyproject.toml 和 uv.lock
uv init my_uv_project
# init 过程中会默认生成 .gitignore 文件,如果你当前暂不涉及仓库和版本管理,你可以通过参数配置默认不生成该文件:
uv init my_uv_project --vcs none
# 进入项目目录
cd my_uv_project
# 创建虚拟环境(默认在 .venv 目录)
uv venv
# 激活环境(和 venv 完全一样)
.venv\Scripts\activate # Windows
source .venv/bin/activate # macOS / Linux
# 添加依赖(自动更新锁文件,uv.lock 可以锁定实际安装的依赖的精确版本,这里以 fastapi 为例)
uv add fastapi uvicorn
# 安装项目所有依赖(包括开发依赖)
uv sync
# 运行主脚本
uv run python script.py
临时安装包试用(不污染项目)
uv tool run black --check .
3.4 常用命令速查
| 操作 | uv 命令 | 传统命令对比 |
|---|---|---|
| 创建虚拟环境 | uv venv |
python -m venv .venv |
| 安装依赖 | uv add requests |
pip install requests + 手动更新 requirements.txt |
| 安装所有依赖 | uv sync |
pip install -r requirements.txt |
| 删除依赖 | uv remove requests |
pip uninstall requests + 手动删除 |
| 锁定依赖版本 | 自动生成 uv.lock |
手动维护 requirements.txt 或使用 pip freeze |
| 更新所有包到最新 | uv sync --upgrade |
pip install --upgrade -r requirements.txt(无法保证版本一致性) |
| 查看当前环境依赖树 | uv tree |
pip list(不显示层级关系) |
3.5 管理不同 Python 版本
uv 可以像 conda 一样自动下载并切换 Python 版本:
# 创建环境时指定 Python 版本(自动下载)
uv venv --python 3.11
# 运行脚本时指定
uv run --python 3.12 script.py
3.6 uv sync 命令执行流程
uv sync 是 uv 最核心的命令之一,它在背后完成了五个步骤:
- 读取 pyproject.toml:获取项目依赖声明
- 处理 uv.lock:
- 无锁文件:解析依赖树,生成新的
uv.lock- 有锁文件:对比pyproject.toml的变化,按需更新锁文件 - 准备虚拟环境:自动创建或复用
.venv目录 - 并行下载依赖:所有包同时下载,利用缓存加速
- 安装到虚拟环境:按依赖树顺序安装,保证版本一致
uv.lock?} end B --> C C -->|有| D[读取 uv.lock] C -->|无| E[解析依赖树
生成 uv.lock] subgraph Processing["依赖处理"] direction LR F[对比变化
更新锁] G[创建/校验
.venv] end D --> F E --> G subgraph Installation["安装阶段"] H[并行下载依赖] I[安装到
虚拟环境] end F --> G G --> H --> I I --> J[完成] style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style C fill:#fff3cd,stroke:#856404,stroke-width:2px style D fill:#d4edda,stroke:#155724,stroke-width:2px style E fill:#d1ecf1,stroke:#0c5460,stroke-width:2px style H fill:#f8d7da,stroke:#721c24,stroke-width:2px style I fill:#d4edda,stroke:#155724,stroke-width:2px style J fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px
4. pyproject.toml 配置指南
4.1 pyproject.toml 的生成方式
pyproject.toml 是现代 Python 项目的标准配置文件,统一了项目元数据、构建系统和依赖声明。
使用 uv init 可以自动生成 pyproject.toml
uv init my_project # 初始化项目
cd my_project # 进入项目目录
此时 uv 会自动创建 pyproject.toml 文件,内容如下:
[project]
name = "my_project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.8"
dependencies = []
只需要手动补充 description、dependencies 等字段即可。
4.2 完整配置文件示例
[project]
name = "my_project"
version = "0.1.0"
description = "A simple web API"
authors = [
{name = "Your Name", email = "you@example.com"}
]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.8"
dependencies = [
"fastapi>=0.100.0",
"uvicorn>=0.23.0",
"requests>=2.31.0",
]
[project.optional-dependencies]
# 可选依赖组,安装时使用 uv sync --extra dev
# 与 [tool.uv] dev-dependencies 的区别:
# - optional-dependencies 是 PEP 735 标准,其他工具(pip, Poetry 等)也支持
# - tool.uv.dev-dependencies 是 uv 特有配置,仅 uv 识别
dev = [
"pytest>=7.0.0",
"black>=23.0.0",
"ruff>=0.1.0",
]
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[tool.uv]
dev-dependencies = [
"pytest>=7.0.0",
]
4.3 核心字段说明
| 字段 | 含义 | 是否必填 |
|---|---|---|
name |
项目名称(PyPI 上要唯一) | 必填 |
version |
版本号(遵循语义化版本) | 必填 |
description |
简短描述 | 必填 |
requires-python |
支持的 Python 版本范围 | 推荐 |
dependencies |
生产环境依赖包列表 | 推荐 |
optional-dependencies |
可选依赖(如测试、开发工具) | 可选 |
authors / license |
作者和许可证信息 | 可选(开源项目推荐) |
4.4 dependencies字段的快速补全
我们通过 uv add 命令添加依赖后,相关依赖及版本信息会自动添加到 pyproject.toml 中,无需手动添加。
4.5 关于 pyproject.toml 的常见问题
问:单文件脚本需要 pyproject.toml 吗?
不需要。直接用 uv run script.py,它会自动管理依赖,无需 pyproject.toml。
问:pyproject.toml 和 requirements.txt 能共存吗?
能。uv sync 会以 pyproject.toml 为准,requirements.txt 会被忽略。但 uv pip install -r requirements.txt 仍然支持,兼容旧项目。
问:没有 pyproject.toml 能用 uv sync 吗?
不能,uv sync 必须依赖 pyproject.toml。但你可以用 uv pip install 替代(兼容 pip 模式),只是享受不到锁机制。
5. 工具选型决策指南
5.1 决策流程图
管理非 Python 依赖?} subgraph Branch1["分支1: 需要非Python依赖"] direction LR C{是否数据科学/
ML项目?} end B -->|是| C C -->|是| D[使用 Conda] C -->|否| E[考虑 Conda 或
系统包管理器 + venv] subgraph Branch2["分支2: 纯Python项目"] direction LR F{是否需要
切换Python版本?} end B -->|否,纯Python| F F -->|是| G[使用 Conda 或 uv] F -->|否| H{是否追求
最快速度?} subgraph Branch3["分支3: 纯Python且
无需切换版本"] direction LR I[使用 uv] J[使用 venv] end H -->|是| I H -->|否| J style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#fff3cd,stroke:#856404,stroke-width:2px style C fill:#fff3cd,stroke:#856404,stroke-width:2px style D fill:#d4edda,stroke:#155724,stroke-width:2px style E fill:#f8d7da,stroke:#721c24,stroke-width:2px style F fill:#fff3cd,stroke:#856404,stroke-width:2px style G fill:#d4edda,stroke:#155724,stroke-width:2px style H fill:#fff3cd,stroke:#856404,stroke-width:2px style I fill:#c3e6cb,stroke:#155724,stroke-width:2px style J fill:#e2e3e5,stroke:#383d41,stroke-width:2px
5.2 工具对比速览
| 特性 | venv | Conda | Poetry | uv |
|---|---|---|---|---|
| 安装包体量 | 轻量 | 较重(Miniconda ~50MB) | 轻量 | 轻量 |
| Python 版本管理 | 不支持 | 支持 | 支持(1.2+) | 支持 |
| 非 Python 依赖 | 不支持 | 支持 | 不支持 | 不支持 |
| 跨语言支持 | 不支持 | 支持 | 不支持 | 不支持 |
| 锁文件 | 不支持 | 可选 | 支持 | 支持 |
| 依赖解析速度 | 快 | 慢 | 中等 | 极快 |
| 学习曲线 | 低 | 中等 | 中等 | 低 |
| 适合数据科学 | 不适合 | 适合 | 一般 | 一般(配合 pip) |
5.3 选型建议
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 数据科学 / 机器学习 | Conda | 自动管理 CUDA、MKL 等底层依赖,跨平台一致性好 |
| 个人纯 Python 新项目 | uv | 极速、现代化、学习成本低 |
| AI 项目且用 PyTorch/TensorFlow | Conda | 自动配置 CUDA,避免手动踩坑 |
| 团队协作(非数据科学) | uv | 锁文件保证版本一致性 |
| 老旧服务器跑脚本 | venv | 够用,无需额外工具 |
| 教学 / 新手入门 | Conda | 预装所有常用包,开箱即用 |
| 轻量级 Web 后端 | uv | 速度快,依赖管理清晰 |
| 追求极致速度 | uv | Rust 实现,安装快 10-100 倍 |
6. 总结
6.1 核心内容回顾
venv是 Python 内置的轻量级虚拟环境工具,适合基础需求和简单项目- Conda 是跨语言的环境管理方案,特别适合数据科学和需要非 Python 依赖的场景
- uv 是新一代极速工具,用 Rust 编写,速度比 pip 快 10-100 倍
- pyproject.toml 是现代 Python 项目的标准配置文件,统一管理项目元数据和依赖
- 工具选型应根据项目类型、团队规模和具体需求综合决策
6.2 常见问题与解答
问:Conda 和 pip 可以混用吗?
可以,但有最佳实践:优先用 conda 安装,conda 没有的包再用 pip 安装。导出环境时用 conda env export --from-history 只保留显式安装的包,避免版本冲突。
问:uv sync 和 pip install -r requirements.txt 有什么区别?
uv sync 基于 pyproject.toml 和 uv.lock 工作,能保证跨环境的版本一致性。pip install -r requirements.txt 只是按列表安装,不会自动处理依赖的依赖版本锁定。
问:如何从 requirements.txt 迁移到 uv?
创建 pyproject.toml 并将依赖填入 dependencies 列表,然后运行 uv sync。uv 会自动生成 uv.lock 并安装所有依赖。
问:团队协作应该选哪个工具?
团队协作的核心需求是版本一致性。推荐使用 uv,它能通过锁文件保证所有开发者使用完全相同的依赖版本。
举手提问