正在加载,请稍候…

Python 虚拟环境详解:venv、conda 和 pyenv

掌握 Python 环境管理,使用 venv、pip、conda 和 pyenv 创建隔离环境、管理依赖并避免版本冲突。

Python 虚拟环境详解:venv、conda 和 pyenv

为什么需要 Python 虚拟环境

默认情况下,Python 包会全局安装。当不同项目需要不同版本的包时,会导致版本冲突:

项目 A:需要 Django 4.2
项目 B:需要 Django 3.2

# 没有虚拟环境:只能安装一个版本
# 新安装的版本会覆盖旧版本,导致其中一个项目无法运行

虚拟环境创建了独立的 Python 安装,每个项目拥有自己的库版本,互不干扰。

Python 虚拟环境详解:venv、conda 和 pyenv 示意图

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 的最前面,因此 pythonpip 命令会使用环境中的副本。

管理包

# 安装包
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

Python 虚拟环境详解:venv、conda 和 pyenv 示意图

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 上的包

Python 虚拟环境详解:venv、conda 和 pyenv 示意图

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 数据。