用pip生成requirements.txt的四种主流方式与避坑指南
你有没有过这种经历项目代码明明在自己电脑上跑得好好的发给同事或者传到服务器上一运行就是满屏的ModuleNotFoundError。然后你打开对方的环境一看——缺了十几个第三方库版本还不一致。追根溯源就是打代码包的时候漏了一件事没有把依赖清单一起交付。这份清单在 Python 项目里就是requirements.txt而生成它最顺手、最常用的工具就是每个 Python 开发者天天都在用的pip。这篇文章我会从一个实际项目的角度把pip生成requirements.txt的几种主流方式都捋一遍包括pip freeze、pipreqs、pip-tools这些工具怎么选、怎么用以及我在真实项目中踩过的坑Windows 下pip无法识别、系统 Python 报externally-managed-environment、生成出来的清单又臭又长不好维护…… 新手朋友可以直接照抄操作步骤有经验的朋友也可以重点看第三、四章的工具选型和排查思路。1. 为什么每个 Python 项目都需要一份 requirements.txt1.1 从项目复现的痛点说起我刚开始写 Python 的时候也懒得管依赖觉得“代码能跑就行”。直到有一次把一个爬虫项目发给朋友跑他那边报错的点跟代码逻辑完全没关系全卡在第三方库上requests没装、lxml版本太老、pandas装了 2.x 但代码里用的接口在 1.x 里才有。我那天远程指导他装库装了快两个小时比我自己重写一遍还累。后来我才意识到所谓“项目可复现”不只是代码本身对还包括它的运行环境是确定的。你把.py文件递给别人别人光是猜测需要哪几个第三方包就得费半天劲就算知道了包名版本不锁定对方也可能装到不一样的行为。requirements.txt就是用来一次性说清楚“我这个项目依赖哪些包、分别是哪个版本”的声明文件。它解决的是三个层面的问题新人接手项目时不用问“还需要装什么”部署到服务器或容器时能精确还原开发环境以及回滚时能快速切回旧版依赖组合。说白了这就是一份“环境快照清单”。1.2 requirements.txt 到底记录了什么很多人以为requirements.txt就是个简单的包名列表其实它的语法有自己的一套规则pip解析时完全按照 PEP 508 规范来读取。最常见的格式是精确版本锁定requests2.31.0最低版本约束requests2.20区间约束requests2.20,3.0兼容版本约束requests~2.31等价于2.31,3.0还能写注释用#开头以及通过-r other.txt引入其他依赖文件通过-e .安装当前项目本身。我见过不少大型项目把requirements拆成base.txt、dev.txt、prod.txt再用-r串起来这也是这套语法灵活的地方。pip读取这份文件时会按照文件里的约束去 PyPIPython 官方包索引或你配置的镜像源拉取对应版本。所以requirements.txt不光是“给人看的”更是“给 pip 执行的脚本”。理解了这一点你就知道为什么它的格式规范这么重要格式一乱pip install -r就会直接报错。2. 用 pip 生成 requirements.txt 的四种主流方式2.1 pip freeze一条命令快速导出如果只记一个命令那就是pip freeze。它会把当前 Python 环境里通过pip安装的所有第三方包连同精确版本号一次性列出来再加个重定向符就能写入文件pip freeze requirements.txt执行完后打开requirements.txt里面就是类似这样的内容certifi2024.2.2 charset-normalizer3.3.2 idna3.6 requests2.31.0 urllib32.2.1pip freeze最大的优势是快、全覆盖不遗漏任何通过pip装进去的东西。但我必须提醒你它导出的是“环境中所有包”不是“项目真正用到的包”。如果你的环境是全局 Python里面可能有你半年前装来玩儿的flask、测试用的pytest甚至和你项目毫无关系的jupyter这些全都会被写进requirements.txt。所以我的习惯是pip freeze只在虚拟环境里用。配合venv或conda创建的干净环境导出结果才等于项目真实依赖。2.2 pipreqs只扫描实际用到的包pip freeze的问题是“给环境做快照”而更多时候我们想要的是“给项目代码做清单”。这时候就该用pipreqs。pipreqs的原理是扫描你项目目录里所有.py文件提取其中的import语句然后去 PyPI 反查包名生成一份只包含“代码里真正被引用到”的依赖清单。它不属于pip自带工具需要单独安装pip install pipreqs进入项目根目录后执行pipreqs . --encodingutf8 --force注意我加的两个参数--encodingutf8是防止 Windows 下读取代码文件时出现中文注释导致的编码报错--force是覆盖已存在的requirements.txt。生成出来的清单一般非常干净比如你代码里只 import 了requests、pandas、jieba它就不会把urllib3这种传递依赖写进去。pipreqs也不是万能的。它对动态导入importlib.import_module这种、字符串形式的 import、写在配置文件里的包名会漏检对包名和模块名不一致的库也可能给出错误结果。比如pillow的模块名是PILpipreqs在处理时需要靠它内置的映射表来判断万一没命中就得手动补一下。2.3 pip-tools拿捏版本范围的优雅方案pipreqs解决了“清单不干净”的问题但和团队协作、长期维护结合起来看还有一个痛点直接锁定精确版本虽然可靠但升级依赖时要全局改一遍。而且pip freeze生成的清单里充满传递依赖升级一个小版本可能引发连锁反应。如果你想用更省心的方式管理依赖版本我推荐pip-tools。它的工作流分两步你维护一个requirements.in文件里面只写“顶层依赖”和宽松的版本范围甚至不写版本号requests pandas2.0 flask用pip-compile编译生成锁定了精确版本的requirements.txtpip-compile requirements.inpip-compile会自动解析依赖关系把传递依赖也写进最终的requirements.txt并在文件头部标注生成时间和使用的工具版本。以后想升级某个包只需要改requirements.in再重新跑一次pip-compile就行了。这套流程对单个项目可能显得重但用到多个项目长期维护、或者 CI/CD 需要可重复构建的场景收益非常明显。我在维护一个内部工具库的时候就是用pip-tools每次发布前重新编译一份锁文件回滚时直接切旧 lock 文件基本没出过依赖事故。2.4 手工精修把 requirements.txt 变成一份可读文档工具生成只是第一步真正专业项目的requirements.txt通常还会经过手工整理。我见过最好的做法是把依赖分组并加注释# 核心运行时依赖 requests2.31.0 flask3.0.3 redis5.0.3 # 数据处理 pandas2.0,2.2 numpy~1.26 # 测试 pytest8.0 pytest-cov4.0注意这里的版本写法核心依赖尽量用精确锁定保证生产环境稳定对有一定兼容余量的库用范围约束比如2.0,2.2既避免装到太老版本也防止大版本升级带来的破坏。另外还有一个小技巧如果项目需要支持不同的 Python 版本可以使用环境标记语法例如pywin32306; sys_platform win32这样写的意思是只有 Windows 平台才安装pywin32其他平台自动跳过。这个语法是 PEP 508 的标准能力pip原生支持很多新手不知道配合跨平台项目特别好用。3. 实操从零到一完成依赖导出与复现3.1 环境准备虚拟环境与 pip 自身确认生成requirements.txt的第一步不是直接敲命令而是先确认自己身在哪个环境。前面说了全局环境下用pip freeze会把一堆无关包带进来所以强烈建议先建虚拟环境。Python 3.3 之后自带venv模块不需要额外安装。一条命令创建一条命令激活python -m venv .venvWindows 下激活.venv\Scripts\activatemacOS 或 Linux 下激活source .venv/bin/activate激活之后命令行提示符前面会出现(.venv)的前缀这表示你已经处在独立环境里了。此时检查pip是否能正常工作我习惯用python -m pip而不是直接pippython -m pip --version这里要解释一下为什么直接敲pip依赖的是系统 PATH 里能找到pip.exe或pip脚本一旦 Python 安装时没把Scripts目录加进 PATHWindows 下就会报“无法将 pip 项识别为 cmdlet、函数、脚本文件或可运行程序的名称”。而python -m pip是“让 Python 解释器以模块方式运行 pip”无论 PATH 怎么配只要python本身能跑这条命令就不会出错。3.2 生成完整 requirements.txt 并验证环境确认无误后有两种典型的生成场景。如果你拿到的是一个从没装过依赖的新环境准备安装项目所需的包pip install requests flask pandas装完后一键导出pip freeze requirements.txt如果你想确认当前环境里已有的包之间有没有版本冲突可以顺手跑一下pip checkpip check会扫描所有已安装包的依赖关系找出互相冲突的组合。输出为空表示一切正常如果有问题它会明确告诉你哪个包要求什么版本、但当前环境里装的是哪个版本。生成之后一定不要急着收工打开requirements.txt看一眼重点确认几件事是否包含项目真正用到的核心包版本号是否都完整不该出现pkg这种没有版本号的裸行有没有明显与当前平台绑死的包比如pywin32、pymssql这类有没有包含一些大型 GUI 库却和项目无关这是全局环境导出的通病。我见过有人直接把全局环境的pip freeze结果发给别人里面带了matplotlib、notebook、pyside6等一堆重库安装起来又慢又容易冲突。这种文件与其叫requirements.txt不如叫环境备份。3.3 新环境完整复现pip install -r 实战有了requirements.txt在另一台机器或新环境里复现项目就变成一条命令的事pip install -r requirements.txt但在实际执行时有几个细节决定了体验差异。首先是国内下载太慢的问题。如果你直接走官方 PyPI几百 MB 的依赖组合能等到怀疑人生。我强烈建议配一个国内镜像源比如清华 PyPI 镜像pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple或者一劳永逸把镜像配置写进 pip 的全局配置文件。Windows 下在用户目录创建pip.iniLinux/macOS 下创建pip.conf[global] index-url https://pypi.tuna.tsinghua.edu.cn/simple配置之后之后所有pip install都不用再带-i参数。镜像源可以理解为一个 PyPI 在国内的缓存仓库里面的包内容跟官方一致只是下载速度快几个量级。其次pip install -r遇到版本冲突时会中断安装并且提示具体是哪两个包在争抢依赖。此时最常见的处理方式是升级依赖解析策略。pip 默认使用--resolverfactory或旧版兼容策略如果你遇到奇怪的解析失败可以尝试pip install --resolverbacktracking -r requirements.txtbacktracking解析器会在依赖约束冲突时主动回溯尝试不同版本组合是 pip 22.0 之后的推荐默认策略能解决很多“明明都满足单个约束但组合安装失败”的诡异问题。4. 常见问题与排查技巧实录4.1 pip 未识别、未安装的情况热词里出现频率最高的报错是pip : 无法将“pip”项识别为 cmdlet、函数、脚本文件或可运行程序的名称这是 Windows 下最常见的 PATH 配置问题。解决思路很简单不要直接pip改用python -m pip。但更深层的问题是这个环境压根没有 pip。Python 3.4 之后的 Linux 发行版里系统 Python 默认不带 pipWindows 上如果在安装 Python 时没有勾选 “pip” 组件也会出现 pip 缺失。拿到这种环境的正确姿势是先确保python命令能用然后立刻安装 pippython -m ensurepip --upgradeensurepip是 Python 官方提供的“最小化 pip 安装器”只要解释器存在就能执行。装完之后再用python -m pip -V验证之后所有 pip 操作都建议用python -m pip这种写法来规避 PATH 问题。4.2 externally-managed-environment 报错最近很多人在 Linux 系统上遇到这个报错error: externally-managed-environment这是 Python 3.11 之后引入的 PEP 668 保护机制系统 Python 环境受操作系统的包管理器如 apt、dnf管理不允许你直接用 pip 往里装包防止破坏系统级 Python 环境。报错信息非常直白这段环境不是给你随便折腾的。我看到不少教程让人加--break-system-packages强装这种做法只能应急不推荐长期依赖。正确解法是一开始就建虚拟环境python -m venv .venv source .venv/bin/activate虚拟环境是独立目录PEP 668 的保护只针对系统 Python不会干扰venv。相信我这件事上没有捷径老老实实用虚拟环境可以避开无数后续问题。4.3 提示 must give at least one requirement另一个高频报错是ERROR: You must give at least one requirement to install (see pip help install)这个基本发生在执行pip install -r requirements.txt时原因有几种requirements.txt文件不存在、文件名写错、或者文件内容是空的。最容易忽略的是从 Windows 复制文件名到 Linux 时带了不可见字符或者文件编码是带 BOM 的 UTF-8导致 pip 把第一行解析成空参数。排查思路就三步先ls确认文件存在再用cat -A requirements.txt检查有没有乱码字符最后用python -m pip install -r requirements.txt执行。如果文件为空回到生成步骤pip freeze重新导一次。4.4 依赖版本混乱与复杂项目的整理技巧requirements.txt最常见的坑是生成时环境状态正常但过两个月再装发现某个包的间接依赖升级后引入不兼容行为。这类问题用肉眼很难发现我推荐两个工具配合排查pipdeptree用来查看依赖树pip install pipdeptree pipdeptree它会以树状结构展示当前环境里所有包的依赖关系。看输出你能立刻明白为什么opencv-python装了之后numpy被升级原来是opencv-python对numpy有最低版本要求。还有一个实用命令是pip list --outdated列出所有可升级的包。结合pipdeptree你就可以判断哪些包值得升级、哪些包因为传递依赖绑定了版本不能动。如果依赖本身就很乱另一个非常实用的做法是删掉requirements.txt在干净环境里从项目源码重新生成。开发到一定阶段后用pipreqs扫一遍真实 import陈旧依赖一次性清干净。这是我定期对项目做“依赖大扫除”的固定动作实测下来每次都能减少 10%~20% 的无效依赖。最后总结一下我在实际项目中的固定流程初始化仓库时建好虚拟环境依赖管理工具优先用pip-tools平时开发不管requirements.txt只维护requirements.in要发布或分享时跑一次pip-compile生成锁版本如果是快速验证的小脚本就直接pip freeze requirements.txt完事。这套流程兼顾了效率和可维护性踩过几次坑之后你会发现一份干净的依赖清单比代码本身更值得认真对待。

相关新闻

AnyPS5远程串流实战:从局域网到广域网,打造低延迟跨设备游戏方案

AnyPS5远程串流实战:从局域网到广域网,打造低延迟跨设备游戏方案

1. 从“AnyPS5”这个标题说起:它到底想解决什么问题第一次看到“AnyPS5”这个标题,我脑子里蹦出来的第一反应是:这大概率是一个围绕“跨平台串流”或者“远程访问”做文章的项目。为什么这么判断?因为“Any”这个前缀在技术圈里几…

2026/10/13 8:15:21 阅读更多 →
代码审查流程设计:从形式化到开放透明的工程化实践

代码审查流程设计:从形式化到开放透明的工程化实践

最近一段时间,我一直在打磨一套名叫open-code-review的代码审查流程。熟悉我的同事都知道,我平时最烦的不是业务逻辑写错,而是“代码过了,人没看明白”。代码审查这件事,几乎每个团队都在做,但绝大多数团队…

2026/10/13 8:13:47 阅读更多 →
open-code-review:让代码评审从走过场变成可复用团队资产

open-code-review:让代码评审从走过场变成可复用团队资产

1. 从“代码评审”这件事说起“open-code-review”这个标题,第一次看到的时候我脑子里冒出来的第一个念头是:这到底是一个开源项目,还是一套评审方法论,又或者是一个把评审流程公开化的实践?后来仔细琢磨了一下&#x…

2026/10/13 8:13:23 阅读更多 →

最新新闻

实习和校招到底在选什么?从简历到面试的完整求职指南

实习和校招到底在选什么?从简历到面试的完整求职指南

1. 实习和校招到底在选什么很多同学第一次接触实习和校招的时候,脑子里冒出来的第一个问题往往是“我该投哪家”“简历怎么写”“面试问什么”。这些问题当然重要,但如果只盯着这些操作层面的东西,很容易陷入一种“做了很多准备却始终不得要领…

2026/10/13 16:36:05 阅读更多 →
xqffi 使用指南:用 PyO3 在 Python 中调用 XQuad Rust 虚拟机(xqvm + xqasm)

xqffi 使用指南:用 PyO3 在 Python 中调用 XQuad Rust 虚拟机(xqvm + xqasm)

【免费下载链接】xquad A rust implementation of the Quip Networks quantum virtual machine. 项目地址: https://gitcode.com/gh_mirrors/xq/xquad 点击查看 免费下载 xqffi 是 XQuad 工具链的 Python 扩展层:它通过 PyO3)和 .xqasm 汇编…

2026/10/13 16:36:05 阅读更多 →
固定资产管理之—硬件产品的分类

固定资产管理之—硬件产品的分类

企业固定资产品类繁杂:办公电脑、工控设备、仪器仪表、货架机具、IT 硬件、精密配件,传统人工盘点耗时耗力、错盘漏盘频发、资产去向无从追溯。随着数字化资产管理普及,RFID 标签打印机、RFID 发卡器、手持数据采集器、RFID 通道门四款核心硬…

2026/10/13 16:36:05 阅读更多 →
HOG+SVM实战:从特征提取到滑窗检测的完整指南

HOG+SVM实战:从特征提取到滑窗检测的完整指南

简介:本资源是一套基于HOG特征与SVM分类器的手写字符识别完整工程方案,面向计算机视觉入门者、模式识别课程学习者及需要完成相关实验或课程设计的学生。方案以CASIA-NLPR手写字符数据集为处理对象,涵盖特征提取、模型训练与分类预测的完整流…

2026/10/13 16:36:05 阅读更多 →
Frank-Wolfe求解交通用户均衡:SiouxFalls网络实战解析

Frank-Wolfe求解交通用户均衡:SiouxFalls网络实战解析

简介:本资源是一份面向交通工程、运筹优化与智能交通系统方向的Python实践代码包,聚焦用户均衡(UE)问题的算法实现与小规模网络验证,适合交通规划初学者、研究生课程设计及算法爱好者动手复现。资源采用经典Frank-Wolf…

2026/10/13 16:36:05 阅读更多 →
从grep到rea:命令行日志分析工具的字段提取实践

从grep到rea:命令行日志分析工具的字段提取实践

半夜两点,我对着一个 1.8GB 的访问日志发呆。我要在几十万条请求里,把某次超时链路涉及的所有记录捞出来,按请求 ID 拼成完整时间线,再看哪个环节耗时异常。第一反应是 grep,grep 也确实把行筛出来了,但筛完…

2026/10/13 16:35:03 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →