前言
Python 的”依赖地狱”是每个开发者都会遇到的问题:项目 A 需要 Django 2.x,项目 B 需要 Django 4.x,同时系统 Python 还在运行某些旧脚本。当依赖冲突时,要么升级后项目崩,要么降级后功能缺失。
虚拟环境是解决这一问题的标准方案——每个项目独立一套 Python 解释器和依赖,互不干扰。
本文将覆盖:
- venv / virtualenv — 内置与增强版虚拟环境
- pip — 包管理的核心工具
- pip-tools — 依赖锁定方案
- pipenv — 一体化工作流
- Poetry — 现代项目管理的最佳实践
- conda — 数据科学领域的全能选手
为什么需要虚拟环境
不使用虚拟环境的问题
# ❌ 全局安装的祸害
$ pip install requests==2.25.1
$ pip install flask==2.0.1
$ # 某个旧脚本需要 requests==2.20.0,升级后崩了
$ # 项目A需要 Django 2.2
$ pip install django==2.2
$ # 项目B需要 Django 4.0
$ pip install django==4.0 # 覆盖了项目A的依赖!
使用虚拟环境的优势
┌─────────────────────────────────────────────────────────────┐
│ 全局 Python │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 项目 A 虚拟环境 │ │
│ │ Python 3.10 │ │
│ │ Django 2.2, requests 2.25 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 项目 B 虚拟环境 │ │
│ │ Python 3.11 │ │
│ │ Django 4.0, requests 2.28 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
核心优势:
| 优势 | 说明 |
|---|---|
| 隔离性 | 每个项目独立的依赖集合,互不干扰 |
| 可复现 | requirements.txt / Pipfile 精确记录依赖版本 |
| 可清理 | 删除虚拟环境目录即可,不影响系统 |
| 多版本 | 同一项目可用不同 Python 版本测试 |
venv:内置虚拟环境
基础命令
# 创建虚拟环境
python -m venv myenv
# 激活虚拟环境(Linux/macOS)
source myenv/bin/activate
# 激活虚拟环境(Windows)
myenv\Scripts\activate
# 激活后,命令行提示符会显示环境名
(myenv) $ pip --version
# Python 3.10.x from /path/to/myenv/lib/python3.10/site-packages
# 退出虚拟环境
deactivate
虚拟环境目录结构
myenv/
├── Include/ # C 头文件
├── Lib/ # 库文件(Windows)或 lib/(Linux)
│ └── site-packages/ # pip 安装的包
├── Scripts/ # 可执行文件(Windows)
│ ├── activate # 激活脚本
│ ├── activate.bat
│ ├── pip.exe
│ └── python.exe
├── pyvenv.cfg # 配置文件
└── bin/ # 可执行文件(Linux/macOS)
├── activate
├── pip
└── python3
常用配置
# 指定 Python 版本创建
python3.11 -m venv myenv311
# 符号链接系统 site-packages(适合开发)
python -m venv --system-site-packages myenv
# 独立模式(默认,不链接系统包)
python -m venv myenv
# 包含 pip 的最小环境(使用 pip-tools 时推荐)
python -m venv --without-pip myenv
requirements.txt 管理
# 导出当前环境依赖
pip freeze > requirements.txt
# ❌ 不推荐:导出所有包(包含系统包)
pip freeze
# ✅ 推荐:只导出直接安装的包
pip freeze --all | grep -v "^#" > requirements.txt
# 安装依赖
pip install -r requirements.txt
# 安装特定版本
pip install requests==2.25.1
pip install "requests>=2.25,<3.0"
pip:包管理基础
核心命令速查
| 命令 | 说明 |
|---|---|
pip install pkg | 安装包 |
pip install "pkg>=1.0" | 安装满足条件的包 |
pip install -r reqs.txt | 从文件安装 |
pip install -e . | 安装当前目录为可编辑包 |
pip uninstall pkg | 卸载包 |
pip list | 列出已安装的包 |
pip show pkg | 查看包信息 |
pip check | 检查依赖冲突 |
pip download pkg | 仅下载不安装 |
pip cache dir | 查看缓存目录 |
# 查看包详情
pip show requests
# Name: requests
# Version: 2.28.0
# Summary: Python HTTP for Humans.
# Home-page: https://requests.readthedocs.io
# Author: Kenneth Reitz
# License: Apache 2.0
# Location: /path/to/venv/lib/python3.10/site-packages
# Requires: charset-normalizer, idna, urllib3, certifi
# Required-by: django
# 检查依赖完整性
pip check
# No broken requirements found.
# 升级 pip 自身
pip install --upgrade pip
# 升级某个包
pip install --upgrade requests
pip 镜像配置
# 临时使用镜像
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
# 永久配置(Linux/macOS)
mkdir -p ~/.pip
cat > ~/.pip/pip.conf << 'EOF'
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
timeout = 60
[install]
trusted-host = pypi.tuna.tsinghua.edu.cn
EOF
# Windows 用户在 %APPDATA%\pip\pip.ini
requirements 文件格式
# requirements.txt 示例
# 固定版本(最严格)
requests==2.28.0
flask==2.0.1
# 版本范围(允许兼容更新)
requests>=2.25,<3.0
flask>=2.0
# 注释说明
django>=4.0 # Web 框架
# 条件依赖
pywin32>=300; sys_platform == 'win32'
pip-tools:锁文件管理
pip-compile 工作流
# 安装 pip-tools
pip install pip-tools
# 1. 创建 requirements.in(仅列出直接依赖)
cat > requirements.in << 'EOF'
django>=4.0
requests>=2.25
python-dotenv
EOF
# 2. 生成 requirements.txt(精确锁定所有依赖)
pip-compile requirements.in
# 生成的 requirements.txt 包含:
# #
# # This file is autogenerated by pip-compile with python 3.10
# # via: pip-compile requirements.in
# #
# asgiref==3.6.0
# # via django
# certifi @ https://pypi.tuna.tsinghua.edu.cn/simple/certifi/...
# charset-normalizer==3.1.0
# # via requests
# django==4.2
# # via -r requirements.in
# ...
pip-sync 同步环境
# 根据 requirements.txt 安装精确版本
pip-sync requirements.txt
# 同步多个文件
pip-sync requirements.txt requirements-dev.txt
依赖分组管理
# requirements.in(基础依赖)
django>=4.0
requests>=2.25
# requirements-dev.in(开发依赖)
-r requirements.in # 包含基础依赖
pytest>=7.0
black
flake8
# requirements-test.in(测试依赖)
-r requirements.in
pytest-cov
faker
# 分别编译
pip-compile requirements.in -o requirements.txt
pip-compile requirements-dev.in -o requirements-dev.txt
pip-compile requirements-test.in -o requirements-test.txt
# 安装
pip-sync requirements-dev.txt # 包含所有依赖
pipenv:pip + 虚拟环境一体化
核心概念
Pipenv 将 pip + virtualenv + requirements.txt 合并为两个文件:
Pipfile— 声明依赖(类似 package.json)Pipfile.lock— 精确锁定版本(类似 package-lock.json)
基础命令
# 安装 pipenv
pip install pipenv
# 进入项目目录,pipenv 自动创建虚拟环境
cd myproject
pipenv install
# 安装依赖
pipenv install requests # 添加到 Pipfile
pipenv install pytest --dev # 仅开发依赖
# 从 requirements.txt 导入
pipenv install -r requirements.txt
# 激活虚拟环境
pipenv shell
# 运行脚本(自动使用虚拟环境)
pipenv run python app.py
pipenv run pytest
# 锁定依赖
pipenv lock
# 更新依赖
pipenv update # 更新所有
pipenv update requests # 更新单个
# 查看依赖图
pipenv graph
Pipfile 格式
# Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
django = ">=4.0"
requests = "~=2.28"
flask = "*" # * 表示任意版本
[dev-packages]
pytest = "^7.0"
black = "*"
[requires]
python_version = "3.10"
# 指定 Python 解释器路径
[python]
python = "/usr/bin/python3.10"
生产环境部署
# 仅安装生产依赖
pipenv install --production
# 或导出 requirements.txt
pipenv lock -r > requirements.txt
pipenv lock -r --dev > requirements-dev.txt
Poetry:现代 Python 项目管理
安装与初始化
# 安装 Poetry
curl -sSL https://install.python-poetry.org | python3 -
# 或
pip install poetry
# 初始化新项目
poetry new myproject
# 已有项目
cd existing-project
poetry init
pyproject.toml 结构
[tool.poetry]
name = "myproject"
version = "0.1.0"
description = "项目描述"
authors = ["Your Name <you@example.com>"]
readme = "README.md"
packages = [{include = "myproject"}]
[tool.poetry.dependencies]
python = "^3.10"
django = "^4.0"
requests = {version = "^2.28", optional = true}
[tool.poetry.group.dev.dependencies]
pytest = "^7.0"
black = "^23.0"
mypy = "^1.0"
pytest-cov = "^4.0"
[tool.poetry.extras]
http = ["requests"]
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
核心命令
# 安装依赖
poetry install # 安装所有依赖
poetry install --no-dev # 仅生产依赖
poetry install requests # 添加新依赖
# 开发依赖
poetry add pytest --group dev
poetry add black mypy --group lint
# 激活虚拟环境
poetry shell
# 运行命令
poetry run python app.py
poetry run pytest
# 更新依赖
poetry update # 更新所有
poetry update requests # 更新单个
# 锁定文件
poetry lock # 更新 lock 文件
poetry lock --no-update # 仅重新解析
# 查看依赖
poetry show # 树状显示
poetry show --tree
poetry show requests # 查看特定包
打包与发布
# 构建包
poetry build
# 发布到 PyPI
poetry publish
# 发布到 TestPyPI
poetry publish --repository testpypi
# 导出为其他格式
poetry export -f requirements.txt -o requirements.txt
poetry export -f requirements.txt --with dev -o requirements-dev.txt
虚拟环境管理
# 查看虚拟环境位置
poetry env info
# 列出所有虚拟环境
poetry env list
# 删除虚拟环境
poetry env remove python3.10
# 指定 Python 版本
poetry env use python3.11
conda:全能型环境管理
适用场景
| 场景 | 推荐工具 |
|---|---|
| 普通 Python 项目 | Poetry / Pipenv |
| 数据科学/机器学习 | conda |
| 需要系统级依赖 | conda |
| R/Python 混用 | conda |
| CUDA/GPU 环境 | conda |
基本命令
# 创建环境
conda create --name myenv python=3.10
conda create --name myenv python=3.10 django=4.0 requests=2.28
# 激活环境
conda activate myenv # conda 4.6+
source activate myenv # conda 4.6 之前
# 常用命令
conda install numpy pandas scikit-learn
conda install -c conda-forge matplotlib # 从 conda-forge 安装
# 列出环境
conda env list
# 导出/导入环境
conda env export > environment.yml
conda env create -f environment.yml
environment.yml
name: myproject
channels:
- defaults
- conda-forge
dependencies:
- python=3.10
- django>=4.0
- pip
- pip:
- black
- pytest
conda 与 pip 共存
# conda 管理基础包
conda install numpy pandas
# pip 管理没有 conda 版本的包
pip install some-package-only-on-pypi
# 最佳实践:environment.yml 中区分
dependencies:
- python=3.10
- numpy
- pip:
- black # pip 专用
依赖管理最佳实践
项目结构推荐
myproject/
├── pyproject.toml # 项目元数据 + 依赖声明(Poetry)
├── poetry.lock # 精确版本锁定
├── requirements.txt # 或 requirements 文件
├── requirements-dev.txt # 开发依赖
├── .env # 环境变量
├── .gitignore # 排除 venv/ .venv/
└── src/ # 源代码
.gitignore 配置
# Python
__pycache__/
*.py[cod]
*$py.class
# 虚拟环境
venv/
.venv/
ENV/
env/
.env/
# 依赖锁定文件(可选)
# poetry.lock 建议提交
# requirements.txt 建议提交
# requirements-dev.txt 建议提交
# IDE
.vscode/
.idea/
# 测试覆盖率
.coverage
htmlcov/
.pytest_cache/
版本约束策略
# pyproject.toml (Poetry)
# ❌ 固定版本(过于严格)
requests = "2.28.0"
# ✅ 语义版本约束(推荐)
requests = "^2.28" # >=2.28,<3.0
django = "~=4.0" # >=4.0,<4.1
flask = ">=2.0,<3.0" # 明确范围
# ✅ 固定主版本
numpy = ">=1.20,<2.0"
# ✅ 动态版本(仅开发时)
[tool.poetry.group.dev.dependencies]
black = "*" # 总是使用最新
多环境配置
# .env 文件
# 开发环境
DEBUG=True
DATABASE_URL=sqlite:///dev.db
# .env.example(提交到版本控制)
DEBUG=
DATABASE_URL=
# .env.local(本地覆盖,不提交)
DEBUG=True
依赖安全审计
# pip-audit
pip install pip-audit
pip-audit
# safety
pip install safety
safety check
# pipenv + safety
pipenv check
# Poetry
poetry check
CI/CD 集成
# GitHub Actions 示例
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Install dependencies
run: poetry install --no-interaction
- name: Run tests
run: poetry run pytest
排错指南
常见错误与解决方案
错误1:pip 安装失败
# 错误:Microsoft Visual C++ 14.0 is required
# 解决1:安装 Build Tools
# https://visualstudio.microsoft.com/downloads/
# 解决2:使用预编译 wheel
pip install --only-binary :all: package-name
# 解决3:使用 conda 代替
conda install package-name
# 错误:SSL certificate verification failed
# 解决:临时禁用或更新证书
pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org requests
# 或
pip install --cert /path/to/cert.pem requests
错误2:依赖冲突
# 错误:pip install 报依赖冲突
# 诊断:查看冲突详情
pip check
# 使用 pip-tools 精确分析
pip-compile requirements.in --output-file=requirements.txt
# Poetry 自动处理冲突
poetry add package-name
# 如果必须使用冲突版本,考虑:
# 1. 升级相关包到兼容版本
# 2. 使用容器隔离
# 3. 拆分为多个服务
错误3:pipenv 环境问题
# 问题:pipenv shell 无法激活
# 解决1:删除重建
rm -rf .venv
pipenv install
# 解决2:指定 Python
pipenv --python 3.10
# 问题:Pipfile.lock 不同步
# 解决
pipenv lock --clear
pipenv install
错误4:Poetry 虚拟环境位置
# 问题:想用 .venv 目录(与 VS Code 兼容)
# 解决:配置
poetry config virtualenvs.in-project true
# 或设置环境变量
POETRY_VIRTUALENVS_IN_PROJECT=true
# 现在会在项目根目录创建 .venv
ls .venv/
# bin/ lib/ pyvenv.cfg
错误5:多 Python 版本混乱
# 问题:不知道用的是哪个 python
# 诊断
which python
python --version
pip --version
# 在虚拟环境中
pipenv run python --version
poetry run python --version
# 清理所有虚拟环境
rm -rf ~/.local/share/virtualenvs/ # pipenv
rm -rf .venv/ # poetry
错误6:缓存导致的问题
# 问题:安装旧版本失败(缓存了新版)
# 清除 pip 缓存
pip cache purge
# 清除特定包的缓存
pip cache remove requests
# 强制重新下载
pip install --no-cache-dir requests==2.25.1
# poetry 清除缓存
poetry cache clear --all pypi
诊断命令清单
# 环境诊断
which python && python --version
pip list
pip freeze
pip check
# pipenv 诊断
pipenv --version
pipenv --where # 项目路径
pipenv --venv # 虚拟环境路径
pipenv graph
# Poetry 诊断
poetry --version
poetry env info
poetry check
# conda 诊断
conda info
conda list
conda env list
总结
工具选型指南
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 新手入门 | venv + pip | 内置、无需额外安装 |
| 简单项目 | pip-tools | 轻量、版本锁定 |
| Web 开发 | Pipenv 或 Poetry | 一体化工作流 |
| 库开发 | Poetry | 标准化打包 |
| 数据科学 | conda | 系统依赖支持 |
| 微服务 | Poetry + Docker | 隔离 + 容器化 |
命令对照表
┌─────────────────────────────────────────────────────────────────┐
│ 工具命令对照表 │
├──────────────┬──────────────┬──────────────┬────────────────────┤
│ 操作 │ venv/pip │ pipenv │ poetry │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ 创建环境 │ python -m venv │ pipenv install│ poetry install │
│ 激活环境 │ source venv/.. │ pipenv shell │ poetry shell │
│ 安装包 │ pip install │ pipenv install│ poetry add │
│ 卸载包 │ pip uninstall │ pipenv --un │ poetry remove │
│ 列出包 │ pip list │ pipenv graph │ poetry show │
│ 锁定版本 │ pip freeze │ pipenv lock │ poetry lock │
│ 导出依赖 │ pip freeze │ pipenv lock -r │ poetry export │
│ 退出环境 │ deactivate │ exit │ exit │
└──────────────┴──────────────┴──────────────┴────────────────────┘
一句话建议
- venv + pip:够用就好,不需要额外学习
- pipenv:想要一体化体验,但社区热度下降
- Poetry:现代 Python 项目的最佳实践,推荐使用
- conda:数据科学/需要系统级依赖时使用
💡 提示: 无论选择哪种工具,都建议将依赖锁定文件提交到版本控制,确保团队成员和部署环境使用完全一致的依赖版本。 📚 扩展阅读:
原创内容,版权所有。未经授权,禁止转载。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END














暂无评论内容