如果你是从前端转型学习 Python,或者已经掌握了一些 Python 基础后开始接触工程化开发,一个几乎必然会遇到的问题就是:为什么 Python 项目总要单独搭建自己的运行环境?以及 venv、pip、requirements.txt,还有近来非常流行的 uv,它们各自扮演什么角色?
这篇文章不讲其他无关内容,只集中把这个问题彻底讲清楚。
先记住一条主线,后续所有内容都围绕它展开:
Python 解释器
-> 创建 .venv
-> 激活或直接使用 .venv 里的 python
-> 用 pip 安装第三方包
-> 用 requirements.txt 记录传统依赖
-> 或者用 uv 接管环境、依赖和锁文件
简单来说,venv 是 Python 标准库自带的虚拟环境工具。它不是第三方库,也不是一个新的解释器,它的作用非常明确:在你的项目目录里,单独创建一个“隔离空间”,让项目拥有自己的 python 和 pip,以及独立的第三方包存放目录,与系统的全局环境彻底分开。
一、先准确理解 venv
做前端的同学都知道,项目依赖不会一股脑安装到全局,而是放在项目自己的 node_modules 里。
Python 同样需要这种隔离机制,但 .venv 不能简单地等同于 node_modules。
更准确的映射关系如下:
| Python | 前端脑内映射 | 说明 |
|---|---|---|
| Python 解释器 | Node 运行时 | 负责执行代码 |
.venv | 项目级运行环境 | 包含解释器入口、pip、第三方包、第三方命令 |
site-packages | 依赖安装目录 | 第三方包最终放在这里 |
pip | npm / pnpm 的安装能力 | 从 PyPI 安装第三方包 |
requirements.txt | 传统依赖清单 | 记录要安装哪些包和版本 |
uv | 现代项目管理工具 | 管理 .venv、依赖、锁文件和运行命令 |
一句话记住核心区别:venv 负责“在哪安装”,pip 负责“怎么安装”,requirements.txt 负责“安装什么”,而 uv 把这几个环节全部整合了。
Python 环境到底是什么?
别把“环境”想得抽象,它落实到具体操作,只控制这几项:
Python 环境
-> 当前使用的 python 命令入口
-> 当前使用的 pip 命令入口
-> 标准库查找路径
-> 第三方包查找路径 site-packages
-> 第三方包安装出来的命令,比如 pytest、uvicorn
创建好虚拟环境后,项目的目录结构大致如下:
my-python-project/
-> .venv/
-> pyvenv.cfg
-> bin/ 或 Scripts/
-> python
-> pip
-> activate / Activate.ps1
-> lib/python3.x/site-packages/ 或 Lib/site-packages/
-> requests/
-> fastapi/
-> pytest/
-> main.py
-> requirements.txt
在 macOS / Linux 上,典型路径是 .venv/bin/python 和 .venv/lib/python3.12/site-packages/。在 Windows 上则是 .venvScriptspython.exe 和 .venvLibsite-packages。
隔离的本质,其实就是把不同项目的第三方包放在彼此独立的 site-packages 目录里:
项目 A 的 requests 在 project-a/.venv/.../site-packages/
项目 B 的 requests 在 project-b/.venv/.../site-packages/
两个项目同样写 import requests,但只要它们运行时使用的 Python 环境不同,看到的 requests 版本就可以完全不同。这才是隔离的真正意义。
虚拟环境隔离什么,不隔离什么?
它主要管理以下几项:当前终端使用哪个 python 和 pip,pip install 安装的第三方包,以及这些包自带的命令(比如 pytest、uvicorn)。
但它不会影响:操作系统、你的项目源码、系统环境变量,以及 Python 标准库本身。标准库来自创建 .venv 时所引用的基础 Python,因此像 import os、import sys 这类通常无需安装,而 import requests 则必须在当前环境里安装过才行。

pyvenv.cfg 这个小文件是干嘛的?
.venv/pyvenv.cfg 是这个虚拟环境的身份凭证。它记录了两件重要的事情:当前虚拟环境是基于哪个系统 Python 创建的(home 字段),以及是否允许它“借用”系统中的第三方包(include-system-site-packages 字段)。默认情况下,这个值是 false,意味着它是一个完全独立的隔离空间。除非创建时特意加了 --system-site-packages 参数,否则在学习阶段和常规项目中不建议开启,因为这会破坏隔离性。
二、为什么项目需要虚拟环境
如果不使用虚拟环境,依赖就会安装到全局 Python,后续很容易踩坑:
- A 项目需要
Django 4,B 项目需要Django 5,版本冲突,互不兼容。 - 自己电脑能正常跑,同事电脑却缺包或者版本不对。
- 全局环境被各种试验、测试、旧项目的包搞得混乱不堪。
- IDE 选错了解释器,终端能运行,编辑器却一直报“找不到模块”。
pip install看上去成功了,实际运行代码时依然提示ModuleNotFoundError。
虚拟环境最终解决的核心问题只有一个:当前项目到底使用哪个 Python,以及它能访问哪些第三方包。
实践中,建议把虚拟环境命名为 .venv,放在项目根目录下:
my-python-project/
-> .venv/
-> main.py
-> requirements.txt
.venv 文件夹绝对不要提交到 Git,因为它体积大、包含本机路径、与操作系统和 Python 版本强相关,别人无法直接使用。正确的做法是,把 .venv/ 添加到 .gitignore 里,真正提交到仓库的是依赖描述文件。传统项目通常是 requirements.txt,而现代采用 uv 的项目则是 pyproject.toml 和 uv.lock。
三、传统流程:venv + pip + requirements.txt
学习阶段,建议先把传统流程跑通,很多老项目仍在沿用,它的核心流程可以简化成一条线:
创建 .venv -> 激活 .venv -> 安装依赖 -> 运行代码 -> 导出 requirements.txt
先处理系统差异
传统流程里,真正有明显系统差异的是“创建”和“激活”这两步。
# macOS / Linux:
python3 -m venv .venv
source .venv/bin/activate
# Windows PowerShell:
python -m venv .venv
.venvScriptsActivate.ps1
# Windows CMD:
python -m venv .venv
.venvScriptsactivate.bat
激活成功后,终端前面通常会出现 (.venv) 前缀,提示你当前 shell 正在使用项目环境。
激活后命令基本一样
一旦激活了虚拟环境,后续命令在 macOS、Linux、Windows 中基本一致:
python main.py # 运行代码
python -m pip install requests # 安装单个依赖
python -m pip install fastapi uvicorn # 安装多个依赖
python -m pip install -r requirements.txt # 按清单安装依赖
python -m pip list # 查看当前依赖
python -m pip show requests # 查看包的具体位置
python -m pip freeze > requirements.txt # 导出依赖清单
deactivate # 退出虚拟环境
这里建议始终使用 python -m pip 而不是直接写 pip。因为 python -m pip 明确表示“用当前这个 python 对应的 pip 去安装包”,能有效避免不同环境下 pip 和 python 版本不一致的问题。
激活到底做了什么?
激活并不是启动一个新操作系统,也不是进入 Docker 容器。它只是将当前 shell 的 PATH 环境变量进行修改,让 .venv/bin (或 .venvScripts) 目录排在最前面。这样,当你输入 python 或 pip 时,系统第一个找到的就是虚拟环境中的版本。如果不习惯激活,也可以直接用绝对路径调用:
# macOS / Linux:
.venv/bin/python main.py
.venv/bin/python -m pip install requests
# Windows:
.venvScriptspython.exe main.py
.venvScriptspython.exe -m pip install requests
日常开发中激活更方便;而在脚本和 CI/CD 里,直接指定解释器路径更可靠。
第一次接手传统项目
如果新克隆的项目里有一个 requirements.txt,按以下流程操作基本不会出错:
git clone xxx
cd my-python-project
python3 -m venv .venv # 创建环境
source .venv/bin/activate # 激活环境
python -m pip install -r requirements.txt # 安装依赖
python main.py # 运行程序
在 Windows 上只需相应替换创建和激活命令即可。
日常开发节奏
虚拟环境创建好后,每天的工作流程变得非常简单:
cd my-python-project
source .venv/bin/activate
python main.py
deactivate
几个要点需要留意:
.venv通常只需要创建一次,除非你手动删除了它。- 只有当
requirements.txt发生变化后,才需要重新执行pip install -r requirements.txt。 - 代码一定要在激活后的环境里运行。
- 开发结束后记得退出环境。
- 激活后直接使用
python即可,无需每次都写python3。
新增依赖后
传统项目的依赖管理流程很简洁:
python -m pip install requests
python -m pip freeze > requirements.txt
提交代码时只提交 requirements.txt,千万不要把 .venv 文件夹也包含进去。这一点至关重要。
四、检查当前环境
遇到环境问题,最有效的方法是查看路径。
macOS / Linux 上执行:
which python
which pip
python --version
python -m pip --version
python -m pip list
Windows 上用 where 代替 which。
如果返回的路径里含有 .venv,说明当前终端正在使用项目虚拟环境。
VS Code 也要选对解释器
这里单独强调一下,因为这是最常见的问题。你在终端激活了 .venv,不代表 VS Code 也自动使用它。需要手动指定:
Command Palette -> Python: Select Interpreter -> 选择 .venv/bin/python
如果你能在终端正常运行代码,但编辑器提示“找不到模块”,90% 的原因是 VS Code 没有选中正确的 .venv 解释器。
五、pip 和 PyPI
pip 是 Python 最常用的包安装器,默认从 PyPI(可以理解为 Python 生态的 npm registry)下载包。它的工作流程如下:
python -m pip install requests
-> pip 去 PyPI 找 requests
-> 下载 requests 和它依赖的包
-> 安装到当前 Python 环境的 site-packages
这里的关键是“安装到当前 Python 环境”。如果你用的是全局 Python,包就装进全局环境;如果你用的是项目 .venv,包就装进项目 .venv。
常用 pip 命令速查
| 命令 | 说明 |
|---|---|
python -m pip install 包名 | 安装指定包 |
python -m pip install -r requirements.txt | 按清单安装依赖 |
python -m pip freeze > requirements.txt | 导出当前环境依赖 |
python -m pip list | 查看当前环境已安装包 |
python -m pip show 包名 | 查看包版本和安装位置 |
python -m pip uninstall 包名 | 卸载指定包 |
python -m pip --version | 查看 pip 属于哪个 Python |
镜像源只影响下载速度
国内网络较慢时,可以临时使用镜像源加速:
python -m pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
也可以设置为默认源:
python -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
这里需要牢记:镜像源只决定包从何处下载,绝不决定包安装到哪个环境。安装的目标环境,始终取决于当前使用的是哪个 python。
六、现代工程化补充:uv
现在许多新项目开始使用 uv。它并不是让虚拟环境消失,而是把创建和管理虚拟环境、安装依赖、生成锁文件等流程全部整合,变得更加便捷。
一个典型的 uv 项目结构是:
my-python-project/
-> .venv/
-> pyproject.toml
-> uv.lock
-> main.py
注意,.venv 仍然位于项目目录下,这样编辑器能直接识别到解释器。
新建 uv 项目
uv init my-python-project
cd my-python-project
uv add requests
uv run python main.py
当你执行 uv add requests 时,它通常一气呵成地完成以下几件事:更新 pyproject.toml、更新 uv.lock、创建或更新 .venv、把 requests 安装到 .venv 中。
接手 uv 项目
如果项目里包含 pyproject.toml 和 uv.lock,就按 uv 的方式操作:
git clone xxx
cd my-python-project
uv sync
uv run python main.py
uv sync 会根据锁文件同步本地的 .venv 环境。而 uv run 则负责在项目环境里运行命令,它会在运行前自动检查环境是否同步。因此在 uv 项目里,你甚至不需要手动执行 source .venv/bin/activate,因为 uv run python main.py 已经安排好了一切。
uv 项目的常用命令
| 场景 | 命令 | 作用 |
|---|---|---|
| 初始化项目 | uv init my-python-project | 创建新项目 |
| 添加依赖 | uv add requests | 更新配置、锁文件和环境 |
| 删除依赖 | uv remove requests | 移除依赖 |
| 同步环境 | uv sync | 根据锁文件同步 .venv |
| 运行命令 | uv run python main.py | 在项目环境里运行 |
| 手动创建虚拟环境 | uv venv | 创建 .venv |
| 指定 Python 版本 | uv venv --python 3.12 | 用指定版本创建环境 |
老项目只有 requirements.txt 怎么办?
没必要为了使用 uv 而强行迁移。如果项目本来就是 requirements.txt 体系,可以继续使用传统流程,也可以先利用 uv 的 pip 兼容模式来加速安装,而不改变项目结构:
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
python main.py
对应关系是:python -m venv 换成 uv venv,python -m pip install 换成 uv pip install。
什么时候用什么? 建议根据项目里的配置文件来决定:
| 场景 | 推荐方案 |
|---|---|
| 刚开始学习 Python | 先掌握 venv + pip + requirements.txt 这套传统流程 |
老项目只有 requirements.txt | 按传统流程,或为了加速用 uv pip |
| 新项目自己搭建 | 可以考虑直接用 uv init |
团队项目已有 uv.lock | 跟随团队,用 uv sync / uv run |
最容易混淆的一点是:requirements.txt 项目就按 venv + pip 的操作流程走;pyproject.toml + uv.lock 项目就按 uv 的流程走。最怕的是在同一个项目里,一会儿手动 pip freeze,一会儿又 uv add,这样容易混乱。
七、常见问题
1. pip install 安装到了全局?
先执行 which python 或 where python 查看路径。如果返回的路径中没有 .venv,就说明当前终端没有激活项目虚拟环境。
2. macOS / Linux 提示 python: command not found
创建虚拟环境前用 python3 --version 确认,激活后再用 python --version。
3. PowerShell 无法执行激活脚本
这是 Windows 的执行策略限制,临时解决即可:
Set-ExecutionPolicy -Scope Process Bypass
.venvScriptsActivate.ps1
4. 环境乱了,依赖装坏了?
学习阶段最简单的办法就是重建:
deactivate
rm -rf .venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
5. 安装依赖非常慢?
临时使用镜像源加速:
python -m pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
再次强调,镜像源只影响下载速度,不影响目标环境。
6. Linux 提示找不到 venv 模块?
Ubuntu / Debian 系统常见,安装一下即可:
sudo apt install python3-venv
python3 -m venv .venv
7. 终端能运行,编辑器提示找不到包?
编辑器的解释器没有选对。在 VS Code 中,通过 Python: Select Interpreter 选择当前项目的 .venv。也可以用 python -c "import sys; print(sys.executable)" 检查终端和编辑器是否指向了同一个 .venv,这是最直接的验证方法。
