依赖管理与环境隔离
requirements.txt、虚拟环境、版本冲突、uv 极速包管理
- 理解为什么需要虚拟环境
- 掌握 venv/poetry/uv 的使用
- 理解 requirements.txt 与版本锁定
- 解决依赖冲突问题
依赖管理与环境隔离
「在我机器上能跑」是程序员最经典的借口。依赖管理就是消灭这个借口的工具。
为什么需要虚拟环境
# 问题:不同项目需要不同版本的库
# 项目A 需要 django==3.2
# 项目B 需要 django==4.2
# 如果全局安装,只能有一个版本 → 冲突!
# 虚拟环境:每个项目有独立的 Python 环境
# 互不干扰,想装什么版本就装什么版本
# Python 自带 venv
# python -m venv .venv # 创建虚拟环境
# Windows: .venv\Scripts\activate
# Linux/Mac: source .venv/bin/activate
# pip install requests # 装到当前虚拟环境
# deactivate # 退出
# 验证:which python / where python
# 激活后指向 .venv 目录下的 python
print("虚拟环境隔离项目依赖")Astral 用 Rust 写的 uv,比 pip 快 10-100 倍。uv venv 创建环境、uv pip install 装包、uv pip compile 锁定版本。如果你还在用 pip,建议切换到 uv。
requirements.txt 规范
# requirements.txt — 项目依赖清单
# 版本符号含义:
# requests==2.31.0 # 精确版本(锁定)
# requests>=2.28.0 # 最低版本
# requests>=2.28,<3.0 # 范围
# requests~=2.31.0 # 兼容版本(>=2.31,<2.32)
# requests # 不指定版本(最新)
# ✅ 生产环境:锁定精确版本,保证可复现
# django==4.2.7
# djangorestframework==3.14.0
# gunicorn==21.2.0
# ✅ 开发环境分文件:
# requirements.txt # 生产依赖
# requirements-dev.txt # 开发依赖(pytest, black, ruff...)
# requirements-dev.txt 中用 -r requirements.txt 继承
# 生成当前环境的依赖快照
# pip freeze > requirements.txt
# 安装依赖
# pip install -r requirements.txt依赖冲突的排查与解决
# 依赖冲突:A 需要 lib>=2.0,B 需要 lib<2.0
# pip 会报错:ResolutionImpossible
# 排查步骤:
# 1. pip install package 看冲突信息
# 2. pipdeptree 查看依赖树
# pip install pipdeptree
# pipdeptree --packages package_name
# 3. 常见解决方案:
# a) 升级/降级冲突的包
# b) 用 pip install package==version 指定兼容版本
# c) 换用没有冲突的替代库
# d) 用 poetry/uv 的依赖解析器自动解决
# 4. 检查已安装包的安全漏洞
# pip install pip-audit
# pip-audit
# 5. 查看包信息
# pip show django # 版本、依赖、位置
# pip list # 所有已安装包
# pip list --outdated # 可升级的包
print("依赖冲突排查工具")Poetry vs uv vs pip 对比
现代 Python 依赖管理工具对比:
# pip + venv:标准库自带,够用但慢
# python -m venv .venv && pip install -r requirements.txt
# Poetry:一体化项目管理(依赖+构建+发布)
# poetry init / poetry add django / poetry install
# poetry.lock 锁定版本,pyproject.toml 声明依赖
# 缺点:解析速度慢
# uv:Rust 实现,极速,兼容 pip 接口
# uv venv # 创建虚拟环境
# uv pip install -r requirements.txt # 极速安装
# uv pip compile requirements.in -o requirements.txt # 锁定版本
# uvx ruff check . # 临时运行工具(不用安装)
# 推荐新项目直接用 uv
# pip-tools:轻量级锁定方案
# pip-compile requirements.in # 生成锁定文件
# pip-sync # 同步环境
# 企业内部:配置私有 PyPI 源
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple package
# 或在 pyproject.toml / pip.conf 中配置全局源pyproject.toml:现代 Python 项目标准
# pyproject.toml 是 PEP 517/518 定义的现代项目配置文件
# 替代了 setup.py、setup.cfg、requirements.txt 等
# [project]
# name = "myapp"
# version = "0.1.0"
# dependencies = [
# "django>=4.2,<5.0",
# "requests>=2.28",
# ]
# [project.optional-dependencies]
# dev = ["pytest>=7.0", "ruff>=0.1", "mypy>=1.0"]
# [tool.ruff]
# line-length = 100
# select = ["E", "F", "I", "UP", "B"]
# [tool.pytest.ini_options]
# testpaths = ["tests"]
print("pyproject.toml 是现代标准")入职第一天就确认项目的 Python 版本和依赖管理方式。看有没有 requirements.txt、pyproject.toml、poetry.lock 或 uv.lock。永远在虚拟环境里干活,别用 sudo pip install。Docker 部署用多阶段构建,减小镜像体积。
生产环境 requirements.txt 应该怎么写版本?
资深工程师加餐
底层原理 · 大厂视角 · 工程经验,点卡片展开
常见根因:内存泄漏导致 OOM 被系统杀掉、连接/文件句柄没关闭耗尽、事件循环里混入同步阻塞、未捕获异常让进程退出。12-Factor App 的建议很实用:配置环境化、日志当成事件流输出、进程保持无状态(状态放数据库/缓存),这样才能随时加副本做水平扩展。
挑战任务
创建依赖清单
用 pip freeze 命令,列出当前项目需要的 3 个依赖及版本。
课后作业
依赖检查脚本
写一个函数,读取 requirements.txt 并检查每个包是否已安装。