Python venv 虚拟环境

本文面向已有前端开发基础、正在学习 Python 工程化的开发者。

这篇只解决一个问题:

text 复制代码
Python 项目为什么要有自己的运行环境,以及 venv、pip、requirements.txt、uv 分别负责什么。

先记住主线:

text 复制代码
Python 解释器
  -> 创建 .venv
  -> 激活或直接使用 .venv 里的 python
  -> 用 pip 安装第三方包
  -> 用 requirements.txt 记录传统依赖
  -> 或者用 uv 接管环境、依赖和锁文件

venv 是 Python 标准库里的虚拟环境工具。

它不是第三方包,也不是新的 Python 语言版本。它做的事情很具体:在项目目录里创建一套独立的 Python 环境入口,让这个项目有自己的 pythonpip、第三方包目录和第三方命令。

一、先准确理解 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 安装进去的第三方包。
  • 第三方包自带的命令,比如 pytestuvicornblack
  • 当前项目看到的依赖版本。

不主要隔离这些:

  • 操作系统。
  • 你的项目源码。
  • 系统环境变量。
  • 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-packagesfalse,也就是不使用全局第三方包。

如果创建时加了:

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 --versionpython -m pip --version,用到的就是 .venv 里的 pythonpip

如果不想激活,也可以直接使用虚拟环境里的解释器:

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.lockpoetry.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.tomluv.lock,按 uv 的方式来:

bash 复制代码
git clone xxx
cd my-python-project
uv sync
uv run python main.py

uv sync 负责根据 pyproject.tomluv.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

相关推荐
夜微凉41 小时前
三、Spring
java·后端·spring
无聊的老谢1 小时前
Vue 3 + TypeScript 构建大型电信运维平台的前端架构设计
前端·vue.js·typescript
xiaofeichaichai1 小时前
Map / Set / WeakMap / WeakSet
前端·javascript
李可以量化1 小时前
成交量的终极量化策略:价量共振指标完整实现(下篇)
前端·数据库·人工智能
林爷万福2 小时前
GitHub 开源光谱数据处理项目推荐
python·光纤光谱仪
copyer_xyf2 小时前
Python 如何同时做很多事:进程、线程、协程
前端·后端·python
Full Stack Developme3 小时前
Spring Bean 依赖注入
python·spring·log4j
yuhuofei20213 小时前
【Python入门】Python中的元组tuple
python
Full Stack Developme3 小时前
Spring AOP 与 AspectJ
java·后端·spring