
pip freeze > requirements.txt 无法自动生成环境标记(如 python_version >= "3.9"),它仅输出当前环境中已安装包的精确版本快照;真正可维护、可复现的依赖应通过手动编写顶层依赖(如 requirements.in)并结合 pip-compile 或 pipreqs 等工具生成,兼顾语义化约束与跨环境兼容性。
`pip freeze > requirements.txt` 无法自动生成环境标记(如 `python_version >= "3.9"`),它仅输出当前环境中已安装包的精确版本快照;真正可维护、可复现的依赖应通过手动编写顶层依赖(如 `requirements.in`)并结合 `pip-compile` 或 `pipreqs` 等工具生成,兼顾语义化约束与跨环境兼容性。
在 Python 项目依赖管理中,requirements.txt 不应是环境快照的“搬运工”,而应是可读、可维护、可复现的契约文件。pip freeze 的本质是“记录现状”,而非“表达意图”——它不区分直接依赖与间接依赖,不识别条件逻辑,更不会注入环境标记(Environment Markers),例如:
# ❌ pip freeze 生成的典型内容(无环境标记) requests==2.31.0 urllib3==1.26.18 certifi==2023.7.22
而真正体现工程意图的写法应类似:
# ✅ 手动维护的 requirements.in(支持环境标记与灵活版本约束) requests>=2.28.0 click~=8.1.0 pydantic>=2.0.0; python_version >= "3.8" argparse; python_version < "3.7" -e . # 本地开发包(需配合 pyproject.toml 或 setup.py)
⚠️ 注意:pip freeze 永远不会添加 ; python_version < "3.7" 这类标记——因为它既不解析代码中的运行时条件,也不理解项目对 Python 版本的真实兼容边界。
推荐工作流:分层管理 + 工具链驱动
-
顶层依赖人工定义(requirements.in)
只写你明确声明并直接使用的包,采用语义化版本(~=、>=)、环境标记和 -r 引用机制:# requirements/base.in requests>=2.28.0 django~=4.2.0
# requirements/dev.in -r base.in pytest>=7.0 black==23.10.1
-
机器生成锁定文件(requirements.txt)
使用 pip-tools 编译,自动注入哈希校验与环境标记:pip install pip-tools pip-compile --output-file=requirements.txt requirements/in/base.in
输出示例:
立即学习“Python免费学习笔记(深入)”;
requests==2.31.0 \ --hash=sha256:... \ --hash=sha256:... django==4.2.11 \ --hash=sha256:... \ ; python_version >= "3.8" -
部署与验证
在目标环境(相同 Python 版本 + OS 架构)中执行:pip install --no-deps --trusted-host pypi.org -r requirements.txt
避免 pip freeze 直接用于生产环境——它会混入 pip、setuptools、wheel 等元包,甚至残留调试工具(如 ipdb),导致不可控依赖膨胀。
关键避坑指南
- 绝不将 pip freeze 结果直接提交为 requirements.txt:它包含间接依赖、开发包、系统包,破坏最小依赖原则;
- 避免硬编码私有源或 --find-links:换环境即失效,应统一配置 pip config 或 CI 中预设镜像源;
- 动态导入需手动补全:pipreqs 无法识别 importlib.import_module("xxx"),须结合 pip show <pkg> 查其 Requires 字段补充;
- 多环境用 -r 分层,不用复制粘贴:requirements/prod.txt 内容仅为 -r base.txt,确保一处变更全局生效;
-
Docker 构建务必分离缓存层:
COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # ← 此层可复用 COPY . .
最终,requirements.txt 的价值不在“自动生成”,而在“精准表达”。它是一份面向协作与部署的契约——由人定义意图,由工具落实细节,由流程保障一致性。


















