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       # 再激活目标环境 B

venv 没有”从 A 直接跳 B”的单条命令。规范做法是先 deactivateactivate 新的。 直接 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. 对比辨析表

工具来源定位适用场景
venvPython 标准库创建虚拟环境(轻量、官方)大多数项目够用,无额外依赖
virtualenv第三方venv 的”超集”,更快、支持 Python 2老项目 / 需要额外特性
pipenv第三方venv + Pipfile + 依赖管理一体喜欢用 Pipfile 锁版本
poetry第三方依赖管理 + 打包 + venv 一体现代 Python 项目主流选项之一
conda第三方跨语言环境管理(Python + C 库等)数据科学 / 需要非 Python 依赖
uv第三方(Rust 写)极快的 venv + pip 替代追求速度、大型 monorepo
维度venvconda
创建命令python -m venv envconda create -n env python=3.11
激活source env/bin/activateconda activate env
退出deactivateconda 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" → 选 .venv

CI 脚本里推荐直接调 .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
  • ❌ “激活脚本可以双击运行” → 错。activatesource 进当前 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