Python venv 激活与退出 (Virtual Environment Activate & Deactivate)
1. 定义
venv 是 Python 标准库自带的虚拟环境创建工具(Python 3.3+),为每个项目隔离一份独立的 Python 解释器和 site-packages。
激活(activate) 是把当前 shell 的 python / pip 等命令临时指向虚拟环境里的副本;退出(deactivate) 是恢复成系统原来的环境。
形象记法:一台电脑上装了好多 Python,全局那只是”公共厨房”,谁都能进来用,但调料瓶(包)越堆越乱、版本还打架。
venv给你开辟一间独立小厨房,调料瓶自己管自己;激活就是”走进小厨房并戴上专属围裙”,退出就是”摘围裙、走回公共厨房”。
2. 核心概念
| 概念 | 含义 | 备注 |
|---|---|---|
| 虚拟环境 | 一份独立的 Python 解释器 + site-packages 副本 | 不是”另装一个 Python”,而是”另起一个包目录” |
pyvenv.cfg | 虚拟环境根目录的配置文件 | 标记此目录是 venv,记录基础 Python 路径 |
| 激活脚本 | bin/activate(mac/Linux)或 Scripts/activate.bat(Win) | 修改的是当前 shell 的环境变量,不是系统全局 |
VIRTUAL_ENV | 激活后写入的环境变量 | 指向虚拟环境根目录,提示符前缀就靠它 |
deactivate | 激活时定义的 shell 函数 | 只在已激活的当前 shell 里存在 |
| 不复制解释器 | venv 用软链/引用指向基础 Python | 升级基础 Python 可能影响所有 venv |
关键点:激活只影响当前这个 shell 会话。新开一个终端窗口,又回到系统环境——这就是为什么 CI 脚本里要么
source activate && python xxx,要么直接用虚拟环境里的绝对路径调用python。
3. 工作原理
激活脚本做的事其实很轻:
┌─────────────────────────────────────────────────────────┐
│ venv 目录结构 │
│ │
│ myenv/ │
│ ├── bin/ (mac/Linux) │
│ │ ├── activate ← bash/zsh 激活脚本 │
│ │ ├── activate.bat ← Windows cmd │
│ │ ├── Activate.ps1 ← Windows PowerShell │
│ │ ├── python ← 软链到基础 Python 解释器 │
│ │ └── pip ← 该环境专属 pip │
│ ├── Scripts/ (Windows 上对应 bin/) │
│ ├── lib/python3.x/site-packages/ ← 第三方包装在这里 │
│ └── pyvenv.cfg ← 标记 venv + 基础 Python 信息 │
└─────────────────────────────────────────────────────────┘
激活做的事:
1. 把 $PATH 最前面插入 myenv/bin
2. 设置 $VIRTUAL_ENV = /path/to/myenv
3. 修改 shell 提示符,加 (myenv) 前缀
4. 定义一个 deactivate 函数,用于还原以上修改
退activate 做的事:
1. 从 $PATH 移除 myenv/bin
2. unset $VIRTUAL_ENV
3. 还原提示符
4. 删除 deactivate 函数本身
所以
deactivate不是某个全局命令——只有激活后它才存在。在没激活的 shell 里敲deactivate会得到 command not found。
4. 基本用法
# ── 1. 创建虚拟环境(在项目根目录下)──
python3 -m venv .venv # 目录名随意,.venv / venv / env 都常见
# 指定解释器创建
python3.11 -m venv .venv # 用 Python 3.11 创建
/usr/bin/python3 -m venv .venv # 用绝对路径指定基础 Python
# ── 2. 激活(按平台区分)──
# macOS / Linux(bash / zsh)
source .venv/bin/activate
# 等价写法
. .venv/bin/activate
# Windows - cmd.exe
.venv\Scripts\activate.bat
# Windows - PowerShell
.venv\Scripts\Activate.ps1
# 若提示禁止执行脚本,先开权限(一次性):
# Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
# ── 3. 验证是否激活成功 ──
which python # 应指向 .venv/bin/python(mac/Linux)
where python # Windows
echo $VIRTUAL_ENV # 应输出虚拟环境绝对路径
# 提示符前会出现 (.venv) 前缀
# ── 4. 在虚拟环境里安装包 ──
pip install requests pandas
pip install -r requirements.txt
pip list # 只看本环境的包,与全局隔离
# ── 5. 退出虚拟环境 ──
deactivate
# 提示符前缀 (.venv) 消失,python/pip 恢复成系统版本
# ── 6. 删除虚拟环境 ──
# 没有专门命令,直接删目录即可(确保已 deactivate)
rm -rf .venv跨平台速记:mac/Linux 走
bin/activate,Windows 走Scripts/activate.*。Windows 区分 cmd(.bat)和 PowerShell(.ps1)两种脚本。
4.5 在终端里切换环境(从一个环境切到另一个)
常见场景:你想装的包要进 A 环境,但当前终端在 B 环境——需要先切到 A。
先确认当前在哪个环境
which python # 看当前 python 路径(venv)
echo $VIRTUAL_ENV # venv 激活后有值,未激活则为空
conda info --envs # conda:带 * 号的是当前环境venv:切换 = 退出旧的 + 激活新的(两步)
deactivate # 先退出当前环境
source /path/to/envB/bin/activate # 再激活目标环境 Bvenv 没有”从 A 直接跳 B”的单条命令。规范做法是先
deactivate再activate新的。 直接source envB/bin/activate(不先 deactivate)通常也能覆盖过去,但先退出更干净,避免 PATH 层层叠加导致混乱。
conda:一条命令直达(不用先 deactivate)
conda activate envB # 从任何环境直接切到 B,自动处理旧环境
conda deactivate # 退回上一层
conda env list # 列出所有 conda 环境uv 项目:通常不用手动切
uv run python xxx.py # 直接用项目的 .venv 跑,无需 activate
source .venv/bin/activate # 想手动激活也行一句话记忆:venv 是”退出再进”两步,conda 是
conda activate一步直达。 切到目标环境后,再pip install/uv add就会装进这个环境。
5. 对比辨析表
| 工具 | 来源 | 定位 | 适用场景 |
|---|---|---|---|
venv | Python 标准库 | 创建虚拟环境(轻量、官方) | 大多数项目够用,无额外依赖 |
virtualenv | 第三方 | venv 的”超集”,更快、支持 Python 2 | 老项目 / 需要额外特性 |
pipenv | 第三方 | venv + Pipfile + 依赖管理一体 | 喜欢用 Pipfile 锁版本 |
poetry | 第三方 | 依赖管理 + 打包 + venv 一体 | 现代 Python 项目主流选项之一 |
conda | 第三方 | 跨语言环境管理(Python + C 库等) | 数据科学 / 需要非 Python 依赖 |
uv | 第三方(Rust 写) | 极快的 venv + pip 替代 | 追求速度、大型 monorepo |
| 维度 | venv | conda |
|---|---|---|
| 创建命令 | python -m venv env | conda create -n env python=3.11 |
| 激活 | source env/bin/activate | conda activate env |
| 退出 | deactivate | conda deactivate |
| 能否装非 Python 包 | ❌ | ✅(如 numpy 的 MKL 版、R) |
| 速度 | 一般 | 慢,但解决依赖更全面 |
6. 典型工作流
# ── 新项目从零开始 ──
mkdir my-project && cd my-project
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install requests pytest
pip freeze > requirements.txt # 锁定依赖版本
# ── 接手已有项目 ──
git clone <repo>
cd <repo>
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# ── CI / 脚本里不依赖激活:直接用绝对路径 ──
# 不激活也能用虚拟环境里的 python,路径就是 bin/python
.venv/bin/python -m pytest
.venv/bin/pip install -r requirements.txt
# ── VS Code 配置自动激活 ──
# 设置 "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"
# 或 Ctrl/Cmd+Shift+P → "Python: Select Interpreter" → 选 .venvCI 脚本里推荐直接调
.venv/bin/python,省去source activate的 shell 兼容性问题,日志更干净。
7. 常见误区
- ❌ “激活后系统全局的包就被删了” → 错。激活只是把
.venv/bin放到PATH最前面;原系统 Python 和包都还在,只是被”遮住”了,deactivate后立刻恢复可见 - ❌ “venv 会复制一份完整的 Python 解释器” → 错。venv 里的
python通常是指向基础 Python 的软链,复制的只是 site-packages 目录;删基础 Python 会让 venv 失效 - ❌ “
deactivate是全局命令” → 错。它只是激活脚本临时定义的 shell 函数,未激活时不存在;在新 shell 里敲会报 command not found - ❌ “把 .venv 目录提交进 git” → 错。
.venv是机器本地的环境,应写进.gitignore;只提交requirements.txt/Pipfile/pyproject.toml - ❌ “激活脚本可以双击运行” → 错。
activate是source进当前 shell 的,直接./activate执行会在子 shell 里改环境,对当前 shell 没影响 - ❌ “venv 跨平台复制即可使用” → 错。Windows 的
.venv拷到 mac 用不了,软链和脚本路径都不同;应记录依赖列表,到新平台重新创建 - ❌ “退出虚拟环境会卸载已装包” → 错。
deactivate只还原环境变量,包都还在.venv目录里,下次激活继续可用
8. 延伸阅读 / 关联概念
pip/requirements.txt— venv 的搭档,记录项目依赖pyproject.toml— 现代 Python 项目的依赖与构建配置标准uv— Rust 写的极速 venv + pip 替代品,命令几乎兼容python -m venv --help— 查看--system-site-packages、--without-pip等选项- 官方文档:venv — Creation of virtual environments