为什么需要 Python 虚拟环境
默认情况下,Python 包会全局安装。当不同项目需要不同版本的包时,会导致版本冲突:
项目 A:需要 Django 4.2
项目 B:需要 Django 3.2
# 没有虚拟环境:只能安装一个版本
# 新安装的版本会覆盖旧版本,导致其中一个项目无法运行
虚拟环境创建了独立的 Python 安装,每个项目拥有自己的库版本,互不干扰。

venv — Python 内置工具
# 创建虚拟环境
python3 -m venv myenv
# 激活(Linux/macOS)
source myenv/bin/activate
# 激活(Windows)
myenv\Scripts\activate.bat # CMD
myenv\Scripts\Activate.ps1 # PowerShell
# 你会看到 shell 提示符中出现 (myenv) 前缀
(myenv) $ pip install requests
# 退出虚拟环境
deactivate
激活时发生了什么?
which python # 之前:/usr/bin/python3
source myenv/bin/activate
which python # 之后:/path/to/myenv/bin/python
激活操作将环境的 bin/ 目录添加到 PATH 的最前面,因此 python 和 pip 命令会使用环境中的副本。
管理包
# 安装包
pip install requests
pip install "django>=4.2,<5.0" # 版本约束
pip install requests==2.31.0 # 精确版本
# 从 requirements 文件安装
pip install -r requirements.txt
# 列出已安装的包
pip list
pip freeze # 精确版本,适用于 requirements.txt
# 生成 requirements.txt
pip freeze > requirements.txt
# 检查过时的包
pip list --outdated
# 升级包
pip install --upgrade requests
# 卸载
pip uninstall requests
requirements.txt 最佳实践
# requirements.txt — 包含版本约束,而非精确锁定
# 对于你控制的应用程序库
requests>=2.28.0,<3.0.0
django>=4.2.0,<5.0.0
celery[redis]>=5.3.0
# requirements-dev.txt — 不随产品发布的工具
pytest>=7.0.0
black>=23.0.0
mypy>=1.0.0
对于需要可重现性的生产部署:
# 生成锁定的 lockfile
pip freeze > requirements-lock.txt
# lockfile 锁定了所有传递依赖的精确版本
# 部署时使用此文件,而非宽松的 requirements.txt
pyenv — 管理多个 Python 版本
venv 管理包;pyenv 管理 Python 版本本身。
# 安装 pyenv(macOS)
brew install pyenv
# 安装 pyenv(Linux)
curl https://pyenv.run | bash
# 列出可用的 Python 版本
pyenv install --list | grep "3\.12"
# 安装特定版本
pyenv install 3.12.3
pyenv install 3.11.8
# 列出已安装的版本
pyenv versions
# 设置全局默认版本
pyenv global 3.12.3
# 为项目设置本地版本(创建 .python-version 文件)
cd myproject
pyenv local 3.11.8
python --version # 3.11.8(覆盖全局设置)
# 为当前 shell 会话设置版本
pyenv shell 3.10.14

pyenv + venv 工作流
# 1. 进入项目目录
cd myproject
# 2. 设置 Python 版本
pyenv local 3.12.3
# 3. 使用该 Python 版本创建虚拟环境
python -m venv .venv
# 4. 激活
source .venv/bin/activate
# 5. 安装依赖
pip install -r requirements.txt
添加到 .gitignore
# .gitignore
.venv/
venv/
env/
__pycache__/
*.pyc
.python-version # 如果要为团队强制执行 Python 版本,请提交此文件
pip-tools — 更好的依赖管理
pip-tools 将抽象需求与锁定的 lockfile 分离:
pip install pip-tools
# requirements.in — 你的直接依赖(抽象)
cat > requirements.in << EOF
requests>=2.28.0
django>=4.2.0
EOF
# 编译为锁定的 lockfile(包含所有传递依赖)
pip-compile requirements.in -o requirements.txt
# 从 lockfile 安装
pip-sync requirements.txt
# 将所有包更新到最新的兼容版本
pip-compile --upgrade requirements.in
这让你两全其美:.in 文件中可读的直接依赖,.txt 文件中可重现的完整 lockfile。
conda — 科学计算与数据科学
conda 在数据科学领域很流行,因为它也能管理非 Python 依赖(如 C 库、CUDA 等)。
# 创建环境
conda create -n myenv python=3.12
# 激活
conda activate myenv
# 安装包
conda install numpy pandas matplotlib
conda install -c conda-forge scikit-learn # 来自社区频道
# 在 conda 环境中使用 pip 安装(适用于 conda 频道中没有的包)
pip install some-package
# 导出环境
conda env export > environment.yml
# 从文件创建环境
conda env create -f environment.yml
# 列出环境
conda env list
# 删除环境
conda env remove -n myenv
environment.yml
name: data-analysis
channels:
- conda-forge
- defaults
dependencies:
- python=3.12
- numpy>=1.24
- pandas>=2.0
- matplotlib>=3.7
- pip:
- custom-package>=1.0.0 # 仅在 PyPI 上的包

Poetry — 现代依赖管理
Poetry 将环境管理、依赖解析和打包整合在一个工具中。
# 安装 Poetry
curl -sSL https://install.python-poetry.org | python3 -
# 创建新项目
poetry new myproject
cd myproject
# 添加依赖
poetry add requests
poetry add "django>=4.2,<5.0"
poetry add --dev pytest black mypy # 开发依赖
# 安装依赖(自动创建 .venv)
poetry install
# 在环境中运行
poetry run python script.py
poetry run pytest
# 激活 shell
poetry shell
# 更新依赖
poetry update
# 显示依赖树
poetry show --tree
pyproject.toml(Poetry)
[tool.poetry]
name = "myproject"
version = "1.0.0"
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.28.0"
django = ">=4.2,<5.0"
[tool.poetry.dev-dependencies]
pytest = "^7.0"
black = "^23.0"
mypy = "^1.0"
Poetry 会生成 poetry.lock 文件——一个完整的 lockfile,你应将其提交到版本控制以实现可重现的安装。
uv — 现代快速替代方案
uv(来自 Astral)是一个基于 Rust 的新 Python 包管理器,速度比 pip 快 10-100 倍:
# 安装 uv
pip install uv
# 或:curl -LsSf https://astral.sh/uv/install.sh | sh
# 创建虚拟环境
uv venv
# 安装包(比 pip 快得多)
uv pip install requests django
# 从 requirements.txt 安装
uv pip install -r requirements.txt
# 使用 pyproject.toml 工作流
uv add requests # 添加到 pyproject.toml 并安装
uv sync # 从 lock 文件安装所有依赖
选择合适的工具
| 工具 | 最适合的场景 |
|---|---|
| venv + pip | 简单项目,最大兼容性 |
| pyenv + venv | 多个 Python 版本,任何项目类型 |
| pip-tools | 需要可重现构建但不想使用重型工具的团队 |
| Poetry | 现代工作流,打包和发布包 |
| conda | 数据科学,科学计算,非 Python 依赖 |
| uv | 速度关键的工作流,现代项目(快速成熟中) |
常见问题及解决方法
# 激活后 "command not found: python"
which python3 # 改用 python3
python3 -m venv .venv
# 包已安装但无法导入
# 检查是否在正确的环境中
which python # 应指向 .venv/bin/python
# pip 安装到了错误的位置
# 在虚拟环境中切勿使用 sudo 运行 pip
# 如果不小心这样做了:删除 venv 并重新创建
# requirements.txt 在不同平台上不可重现
# 使用 pip-tools 或 Poetry,它们会生成跨平台的 lockfile
→ 使用 JSON Viewer 探索 Python 配置文件与 JSON 数据。