本文面向已有前端开发基础、正在学习 Python 工程化的开发者。
这篇只解决一个问题:
text
Python 项目为什么要有自己的运行环境,以及 venv、pip、requirements.txt、uv 分别负责什么。
先记住主线:
text
Python 解释器
-> 创建 .venv
-> 激活或直接使用 .venv 里的 python
-> 用 pip 安装第三方包
-> 用 requirements.txt 记录传统依赖
-> 或者用 uv 接管环境、依赖和锁文件
venv 是 Python 标准库里的虚拟环境工具。
它不是第三方包,也不是新的 Python 语言版本。它做的事情很具体:在项目目录里创建一套独立的 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、依赖、锁文件和运行命令 |
一句话记:
text
venv 负责隔离环境,pip 负责安装包,requirements.txt 负责记录传统依赖,uv 可以进一步接管项目环境和依赖管理。
Python 环境到底是什么
不要把"环境"理解得太虚。
它主要落在这几件事上:
text
Python 环境
-> 当前使用的 python 命令入口
-> 当前使用的 pip 命令入口
-> 标准库查找路径
-> 第三方包查找路径 site-packages
-> 第三方包安装出来的命令,比如 pytest、uvicorn
创建虚拟环境以后,项目目录一般长这样:
text
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 常见路径:
text
.venv/bin/python
.venv/bin/pip
.venv/lib/python3.12/site-packages/
Windows 常见路径:
text
.venv\Scripts\python.exe
.venv\Scripts\pip.exe
.venv\Lib\site-packages\
所以虚拟环境隔离的重点是:
text
项目 A 的 requests 在 project-a/.venv/.../site-packages/
项目 B 的 requests 在 project-b/.venv/.../site-packages/
两个项目都写:
python
import requests
但只要它们运行时使用的 Python 环境不同,看到的 requests 版本就可以不同。
虚拟环境隔离什么
主要隔离这些:
- 当前终端优先使用哪个
python。 - 当前终端优先使用哪个
pip。 pip install安装进去的第三方包。- 第三方包自带的命令,比如
pytest、uvicorn、black。 - 当前项目看到的依赖版本。
不主要隔离这些:
- 操作系统。
- 你的项目源码。
- 系统环境变量。
- Python 标准库本身。
标准库通常来自创建 .venv 时使用的那套基础 Python。
所以:
python
import os
import sys
import json
通常不用安装,因为它们是标准库。
但:
python
import requests
必须当前环境安装过 requests 才能用,因为它是第三方包。
这张图可以辅助理解"全局 Python"和"项目虚拟环境"的关系:

pyvenv.cfg 是什么
.venv/pyvenv.cfg 是虚拟环境的配置文件。
它通常会记录这类信息:
text
home = /Library/Frameworks/Python.framework/Versions/3.12/bin
include-system-site-packages = false
version = 3.12.x
这里最重要的是两点:
text
home:这个虚拟环境是基于哪套基础 Python 创建的
include-system-site-packages:是否允许访问系统全局 site-packages
默认情况下,include-system-site-packages 是 false,也就是不使用全局第三方包。
如果创建时加了:
bash
python -m venv --system-site-packages .venv
虚拟环境才会允许访问系统全局的第三方包。
学习和普通项目里不建议这样做,因为这会削弱隔离性。
二、为什么项目需要虚拟环境
如果不使用虚拟环境,依赖很容易装到系统全局 Python 里。
后面常见问题是:
- A 项目要
Django 4,B 项目要Django 5,版本互相影响。 - 自己电脑能跑,同事电脑缺包或版本不同。
- 全局环境被学习包、测试包、旧项目包污染。
- IDE 选错解释器,终端能跑,编辑器提示找不到包。
pip install看起来成功了,但运行代码时还是ModuleNotFoundError。
虚拟环境解决的是这个问题:
text
当前项目到底用哪一个 Python,以及当前项目到底能看到哪些第三方包。
项目里推荐把虚拟环境命名为 .venv,放在项目根目录:
text
my-python-project/
-> .venv/
-> main.py
-> requirements.txt
.venv 不要提交到 Git。
原因很直接:
- 体积大。
- 包含本机路径。
- 和操作系统、Python 版本有关。
- 另一台电脑直接复用很容易出问题。
.gitignore 常见写法:
gitignore
.venv/
venv/
__pycache__/
*.pyc
真正应该提交的是依赖描述文件。
传统项目通常是:
text
requirements.txt
现代 uv 项目通常是:
text
pyproject.toml
uv.lock
三、传统流程:venv + pip + requirements.txt
学习阶段先掌握传统流程。
它的优点是简单,很多老项目也还在用。先把流程记成一条线:
text
创建 .venv -> 激活 .venv -> 安装依赖 -> 运行代码 -> 导出 requirements.txt
先处理系统差异
传统流程里,真正明显分系统的主要是"创建"和"激活"。
bash
# macOS / Linux:
python3 -m venv .venv
source .venv/bin/activate
# Windows PowerShell:
python -m venv .venv
.venv\Scripts\Activate.ps1
# Windows CMD:
python -m venv .venv
.venv\Scripts\activate.bat
macOS / Linux 有些机器也可以直接用 python -m venv .venv,前提是 python 命令已经指向正确的 Python 版本。
激活成功以后,终端前面通常会出现:
text
(.venv)
这个提示只是在告诉你:当前 shell 会优先使用 .venv 里的命令。
激活后命令基本一样
激活虚拟环境以后,后面的命令在 macOS、Linux、Windows 里基本一致:
bash
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。它表达的是:
text
用当前这个 python 对应的 pip 去安装包。
这样更不容易出现"pip 和 python 不是同一个环境"的问题。
激活到底做了什么
激活不是启动一个新系统,也不是进入 Docker 容器。
它主要修改当前终端会话的环境变量,让 .venv/bin 或 .venv\Scripts 排到 PATH 前面。所以激活后执行 python --version、python -m pip --version,用到的就是 .venv 里的 python 和 pip。
如果不想激活,也可以直接使用虚拟环境里的解释器:
bash
# macOS / Linux:
.venv/bin/python main.py
.venv/bin/python -m pip install requests
# Windows:
.venv\Scripts\python.exe main.py
.venv\Scripts\python.exe -m pip install requests
日常开发里激活更方便;脚本和 CI 里直接写解释器路径也很常见。
pip freeze > requirements.txt 会把当前环境里安装的包和版本导出成依赖清单。别人接手项目时,再用 python -m pip install -r requirements.txt 把依赖装回自己的 .venv。学习阶段这样够用,但大型项目里它不如 uv.lock、poetry.lock 这类锁文件精确。
第一次接手传统项目
如果项目里有 requirements.txt,可以按这个流程:
bash
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 把创建和激活换成:
powershell
python -m venv .venv
.venv\Scripts\Activate.ps1
每天开发
每天开发通常不需要重新创建 .venv。
bash
cd my-python-project
source .venv/bin/activate
python main.py
deactivate
注意:
.venv通常只创建一次。requirements.txt变化后,再执行python -m pip install -r requirements.txt。- 运行代码应该在项目环境里运行。
- 开发结束后再
deactivate。 - 激活后一般直接用
python,不用一直写python3。
新增依赖后
传统项目里通常这样:
bash
python -m pip install requests
python -m pip freeze > requirements.txt
提交代码时提交 requirements.txt,不要提交 .venv。
四、检查当前环境
环境问题优先查路径。
macOS / Linux:
bash
which python
which pip
python --version
python -m pip --version
python -m pip list
Windows:
powershell
where python
where pip
python --version
python -m pip --version
python -m pip list
如果路径里出现 .venv,说明当前终端正在使用项目虚拟环境。
VS Code 也要选对解释器
终端激活了 .venv,不代表编辑器一定选对了。
VS Code 里需要确认:
text
Command Palette
-> Python: Select Interpreter
-> 选择 .venv/bin/python 或 .venv\Scripts\python.exe
如果终端能跑,但编辑器提示找不到包,大概率是 VS Code 没选中当前项目的 .venv。
五、pip 和 PyPI
pip 是 Python 常用的包安装工具。
默认情况下,pip 会从 PyPI 下载第三方包。PyPI 可以理解成 Python 生态里的 npm registry。
text
python -m pip install requests
-> pip 去 PyPI 找 requests
-> 下载 requests 和它依赖的包
-> 安装到当前 Python 环境的 site-packages
关键点是最后一句:
text
安装到当前 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 |
镜像源只影响下载地址
国内网络慢时,可以临时指定镜像源:
bash
python -m pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
也可以设置默认镜像源:
bash
python -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
查看配置:
bash
python -m pip config list
恢复默认源:
bash
python -m pip config unset global.index-url
注意:
text
镜像源只决定从哪里下载包,不决定包安装到哪个环境。
包安装到哪里,仍然取决于当前使用的是哪一个 python。
六、现代工程化补充:uv
现在很多新 Python 项目会使用 uv。
uv 不是让虚拟环境消失,而是帮你管理虚拟环境、依赖、锁文件和运行命令。
常见结构是:
text
my-python-project/
-> .venv/
-> pyproject.toml
-> uv.lock
-> main.py
uv 项目里,.venv 默认也在项目目录下,方便编辑器找到解释器。
新建 uv 项目
bash
uv init my-python-project
cd my-python-project
uv add requests
uv run python main.py
uv add requests 通常会同时做几件事:
text
更新 pyproject.toml
更新 uv.lock
创建或更新 .venv
安装 requests
接手 uv 项目
如果项目里有 pyproject.toml 和 uv.lock,按 uv 的方式来:
bash
git clone xxx
cd my-python-project
uv sync
uv run python main.py
uv sync 负责根据 pyproject.toml 和 uv.lock 同步本地 .venv。
uv run 负责在项目环境里运行命令。它会在运行前检查锁文件和环境是否需要同步。
所以 uv 项目里不一定要手动执行:
bash
source .venv/bin/activate
因为:
text
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 强行迁移。
如果项目本来就是:
text
requirements.txt
可以继续用传统流程:
bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
也可以用 uv 的 pip 兼容能力加速:
bash
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
python main.py
对应关系:
| 传统写法 | uv 写法 |
|---|---|
python -m venv .venv |
uv venv |
python -m pip install requests |
uv pip install requests |
python -m pip install -r requirements.txt |
uv pip install -r requirements.txt |
什么时候用哪个:
| 场景 | 推荐 |
|---|---|
| 刚开始学习 Python | 先掌握 venv + pip + requirements.txt |
老项目只有 requirements.txt |
按传统流程,或用 uv pip 加速 |
| 新项目自己搭建 | 可以考虑 uv init |
团队项目已有 uv.lock |
按团队方式用 uv sync / uv run |
最容易混的是:
text
requirements.txt 项目:优先按 venv + pip 的传统流程。
pyproject.toml + uv.lock 项目:优先按 uv 流程。
不要在同一个项目里一会儿手动 pip freeze,一会儿又 uv add,除非团队明确要迁移依赖管理方式。
七、常见问题
1. pip install 装到全局了
先看路径:
bash
which python
which pip
python -m pip --version
Windows:
powershell
where python
where pip
python -m pip --version
如果路径没有 .venv,说明当前终端没有使用项目虚拟环境。
2. macOS / Linux 提示 python: command not found
创建虚拟环境前可以用:
bash
python3 --version
python3 -m venv .venv
激活后再用:
bash
python --version
3. PowerShell 无法执行激活脚本
当前会话临时放开执行策略:
powershell
Set-ExecutionPolicy -Scope Process Bypass
然后再激活:
powershell
.venv\Scripts\Activate.ps1
4. 环境乱了,依赖装坏了
学习阶段最简单的方式是重建:
bash
deactivate
rm -rf .venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
Windows 可以手动删除 .venv 目录后重新创建。
5. 安装依赖很慢
临时使用镜像源:
bash
python -m pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
但要记住:镜像源只影响下载速度和下载地址,不影响包安装到哪个环境。
6. Linux 提示找不到 venv 模块
Ubuntu / Debian 常见处理:
bash
sudo apt install python3-venv
python3 -m venv .venv
7. 终端能运行,编辑器提示找不到包
通常是编辑器解释器没选对。
检查:
text
VS Code -> Python: Select Interpreter -> 选择当前项目的 .venv
再检查:
bash
python -c "import sys; print(sys.executable)"
终端和编辑器应该指向同一个项目 .venv。