Python 基础教程:虚拟环境与依赖管理

前言

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              │
└──────────────┴──────────────┴──────────────┴────────────────────┘

一句话建议

  1. venv + pip:够用就好,不需要额外学习
  2. pipenv:想要一体化体验,但社区热度下降
  3. Poetry:现代 Python 项目的最佳实践,推荐使用
  4. conda:数据科学/需要系统级依赖时使用

💡 提示: 无论选择哪种工具,都建议将依赖锁定文件提交到版本控制,确保团队成员和部署环境使用完全一致的依赖版本。 📚 扩展阅读:


原创内容,版权所有。未经授权,禁止转载。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容