pip freeze最可靠,因其输出package==version格式,专为生成requirements.txt以复现环境设计;而pip list --outdated仅显示可升级包,pip show仅查单个包详情,均无法批量导出完整依赖列表。

直接用 pip freeze 最可靠,但要注意它导出的是当前环境所有已安装包(包括间接依赖),不是项目实际需要的最小依赖集。
为什么不用 pip list --outdated 或 pip show?
这两个命令目的不同:pip list --outdated 只显示可升级的包,不输出完整列表;pip show 每次只能查一个包,没法批量导出。真正要“导出依赖列表”,核心就是生成可复现安装的文本文件,pip freeze 是唯一内置且符合该目标的命令。
-
pip freeze输出格式是package==version,兼容pip install -r requirements.txt - 它会包含所有顶层包 + 依赖树里的所有包(比如你装了
requests,也会列出urllib3、chardet等) - 若只想导出“显式安装”的包(忽略自动带进来的依赖),得配合
pipdeptree或手动过滤,pip freeze本身做不到
导出时怎么排除编辑模式安装(-e)和本地路径包?
当项目用 pip install -e . 开发安装时,pip freeze 会输出类似 -e git+https://...@abc123#egg=myproject 的行,这类条目无法被他人直接 pip install。需要过滤:
- 加
--exclude-editable参数(Python 3.12+ pip 23.3+ 支持):pip freeze --exclude-editable > requirements.txt - 旧版 pip 可用
grep -v "^-e "(Linux/macOS)或findstr /v "^-e "(Windows)过滤 - 注意:过滤后丢失的不只是 -e 包,还有以
-e开头的其他合法行(极少见),实际使用中基本无影响
导出结果要不要用 pipreqs 替代?
pipreqs 是第三方工具,它扫描 Python 文件中的 import 语句反推依赖,结果更接近“项目实际用到的包”。但它有明显局限:
- 无法识别运行时动态导入(如
importlib.import_module)、条件导入、字符串 import - 会漏掉配置驱动的依赖(如 Django 插件在
INSTALLED_APPS里声明但没在代码里 import) - 对未安装但代码里写了 import 的包,会报错或跳过,导致结果不全
- 不能处理 C 扩展或非 PyPI 包的依赖声明
所以,除非你明确要“最小化依赖”且能接受人工校验,否则别用 pipreqs 替代 pip freeze —— 它解决的是另一个问题。
导出后如何验证 requirements.txt 是否可用?
最简单的验证方式是新建干净环境并重装:
- 创建新虚拟环境:
python -m venv venv-test - 激活后安装:
venv-test/bin/activate(macOS/Linux)或venv-test\Scripts\activate(Windows) - 执行:
pip install --no-deps -r requirements.txt(先装主包,避免依赖冲突干扰) - 再补装依赖:
pip install -r requirements.txt - 如果报错,大概率是
requirements.txt里混入了平台特定包(如win32api)或版本冲突,需手动清理
真正容易被忽略的是:导出时当前环境可能包含系统级或用户级安装的包(比如通过 --user 装的),pip freeze 默认都会列出来。若要严格限定仅 virtualenv 内安装的包,务必在激活虚拟环境后再运行命令,且确认 which pip(或 where pip)指向的是虚拟环境内的 pip。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











