用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完事。这套流程兼顾了效率和可维护性踩过几次坑之后你会发现一份干净的依赖清单比代码本身更值得认真对待。
报考提示:本文涉及的批次、材料要求可能随上级文件调整,报名前建议再确认一次。你所在的工种、城市、当前进度如果拿不准,可以直接电话 18236992212 或在线预约,我们按你的情况单独捋一遍流程,不白跑。
证书真伪提醒:凡是说"不用考试直接拿证""花钱买证""包过免考"的,基本都是假证或骗局。正规特种作业操作证必须本人参考、本人答题,办下来的证在应急管理部官网、河南省厅平台都能查到电子记录。查不到的证,上岗被查到要担责任,千万别图省事。拿不准的,先打 18236992212 问一句。
报考流程

从咨询到拿证,六步走完

不管这篇资讯讲的是哪个工种,报名到取证的流程都是这六步,照着走不绕弯。

01

咨询定工种

说清岗位和单位要求,确认该考哪类证。

02

材料预审

按清单准备,拍照发来免费预审。

03

报名建档

提交报名信息,同步本批次窗口。

04

考前辅导

理论题库加实操要点针对性训练。

05

参加考试

理论机考加实操考核,按批次安排。

06

取证复审

查证领证,到期前提醒复审换证。

报名咨询前台接待

正规培训通道

走应急管理部门认可的报名与培训渠道,本人参考本人答题。

材料免费预审

报名前拍照发来逐项核对,缺什么错什么当场指出来。

批次提前通知

河南应急厅批次一有消息,第一时间同步报名学员。

费用透明无隐形

报名前把费用明细一次性说清,包含哪些、怎么收都写明。

电话咨询

18236992212,说清工种和城市,我们按你的情况给建议。

邮箱咨询

809451989@qq.com,材料拍照发来,免费预审。

在线预约

留下姓名、电话、工种,我们安排专人回访对接。

濮阳 / 许昌

两地设服务点,就近安排报名与考试对接。

常见问题

关于报考,常被问到的几个问题

看完这篇资讯,下面这些问题顺便一起答了。

我现在报名,大概多久能参加考试?

材料预审通过、报名建档后,一般排在最近的一个批次。具体时间取决于河南应急管理厅当期批次安排和机位,濮阳、许昌本地考点通常每月都有场次。报名时我们会告诉你本批次的报名截止时间和预计考试时间。

没有相关工作经验,能直接考吗?

大部分工种允许零基础报名,经正规培训后参考。部分岗位对学历、体检有要求,具体以工种对照条件为准。不确定自己符不符合的,先说说你的情况,我们帮你判断该报哪个。

考试没过可以补考吗?怎么收费?

理论和实操分别考核,单科不合格一般有补考机会,补考按当期批次重新排期。费用明细我们会在报名前一次性说清,没有隐形收费。

企业要一批人考证,能统一办理吗?

可以。建筑、化工、制造类企业批量申报走企业团报通道,统一建档、对公收费、台账整理一起办,安全管理员配套我们也能对接。

拿到证以后多久要复审?在哪复审?

特种作业操作证每 3 年复审一次,满 6 年需要换证。复审不必须回发证地,濮阳、许昌本地都能办,异地也能对接。建议提前一两个月开始准备,别等证书过期了才想起这件事。

怎么查自己的证是不是真的?

上应急管理部官网或河南省厅政务平台,输入身份证号和证件号就能查电子记录。查不到的、或者有人跟你说"不用考试直接拿证"的,基本都是假证,上岗被查到要担责任,别图省事吃这个亏。

整个下来大概要花多少钱?

不同工种费用不一样,跟培训课时、考试次数挂钩。我们会在报名前把费用明细一次性说清,包含哪些、不包含哪些写在明面上,没有隐形收费。补考另行排期,费用按当期标准走。

我条件好像不太够,还能考吗?

年龄、学历、体检这几项卡得最严,哪项差一点、怎么补,各工种要求不同。别自己猜,把你的情况说清楚——多大年龄、什么学历、有没有相关经验——我们帮你判断该报哪个工种、差的条件怎么补,能考就告诉你怎么考,不能考也不耽误你时间。

个人预约 / 企业团报

文章里没说清的,直接问我们

你的工种、城市、当前进度,说一句就行。材料、批次、费用按你的情况单独捋,不套模板。