Python项目中的第三方库数量一旦增加,手动记录依赖版本很容易造成环境不一致。开发机器能够正常运行,换一台电脑却出现模块缺失、版本冲突,甚至部署到服务器后直接启动失败,很多时候都与依赖管理不规范有关。
requirements文件正是Python项目中最常见的依赖管理方式之一。通过它可以集中记录项目运行所需要的第三方包及版本信息,并结合pip快速完成依赖安装、环境迁移和部署。
一、什么是requirements文件
requirements文件通常命名为requirements.txt,本质上是一个纯文本文件,用于描述Python项目依赖的第三方软件包。
一个简单的requirements.txt可能如下:
Django==5.1.2 requests==2.32.3 PyYAML==6.0.2 pandas>=2.2.0
每一行通常对应一个依赖包,也可以指定版本约束。
例如:
requests==2.32.3
表示安装指定版本。
requests>=2.32.3
表示安装不低于2.32.3的版本。
requests<3.0
表示版本必须低于3.0。
也可以同时指定上下限:
requests>=2.30.0,<3.0.0
这种方式能够在版本兼容性和依赖更新之间取得一定平衡。
需要注意的是,requirements.txt并不是Python语言强制规定的文件格式,而是Python生态中约定俗成的一种依赖描述方式。pip能够读取该文件,并根据其中的内容安装依赖。
二、requirements.txt的主要作用
项目使用requirements文件,核心目的并不是简单保存几个包名,而是让项目运行环境具备可复现性。
1. 快速搭建开发环境
拿到一个新的Python项目后,可以直接执行:
Bashpip install -r requirements.txt
pip会读取文件中的依赖,并自动安装。
相比逐个执行:
Bashpip install requests pip install pandas pip install flask
统一管理更加方便。
2. 保持不同环境的一致性
项目通常会经历开发、测试和生产等多个环境。
如果每个环境自行安装依赖,很容易出现:
开发环境:requests 2.32.3 测试环境:requests 2.31.0 生产环境:requests 2.28.2
某些API或行为发生变化后,就可能出现“本地正常、服务器异常”的问题。
通过requirements文件可以降低这种环境差异。
3. 方便项目部署
服务器部署Python项目时,通常只需要准备Python运行环境,然后执行:
Bashpip install -r requirements.txt
就能够完成大部分项目依赖安装。
4. 方便团队协作
团队成员从Git仓库获取项目后,可以根据requirements文件快速恢复项目依赖,而不需要询问项目开发者“这个项目还需要安装哪些库”。
三、requirements文件常见版本写法
理解版本约束,是正确维护requirements文件的关键。
固定版本
Flask==3.0.3
表示严格安装3.0.3。
固定版本适合对运行环境稳定性要求较高的项目,尤其是生产环境。
大于等于某个版本
requests>=2.31.0
表示允许安装2.31.0及以上版本。
这种写法比较灵活,但如果未来发布的新版本存在兼容性变化,也可能给项目带来风险。
小于某个版本
numpy<3.0
表示版本必须低于3.0。
指定版本范围
Django>=4.2,<5.0
表示允许4.2及以上,但不能达到5.0。
不等于某个版本
urllib3!=2.0.0
表示排除2.0.0版本。
多条件组合
requests>=2.30,<3.0
能够同时限制最低和最高版本。
四、如何生成requirements.txt
已有Python项目时,最常见的方法是使用pip freeze。
首先查看当前环境中的已安装包:
Bashpip freeze
可能得到:
Django==5.1.2 PyYAML==6.0.2 requests==2.32.3 urllib3==2.2.3
将结果保存到文件:
Bashpip freeze > requirements.txt
执行完成后,当前目录下就会生成:
requirements.txt
之后可以查看:
Bashcat requirements.txt
Windows环境则可以直接打开该文件查看。
五、pip freeze并不一定等于项目真正需要的依赖
这是实际开发中非常容易忽略的问题。
假设一个虚拟环境中安装了:
Django requests pytest black jupyter numpy pandas
但项目代码实际上只使用:
Django requests
执行:
Bashpip freeze > requirements.txt
之后,所有安装在当前环境中的包都可能被写入文件。
这会造成requirements.txt越来越庞大,并且混入测试工具、格式化工具以及其他与项目运行无关的包。
因此,pip freeze更准确地说是“记录当前环境”,而不是自动分析“项目实际依赖”。
对于小型项目,可以使用它快速生成依赖清单;对于大型项目,则建议结合虚拟环境、依赖分组或专门的依赖管理工具进行维护。
六、requirements.txt如何安装依赖
拿到项目后,进入项目根目录:
Bashcd myproject
执行:
Bashpip install -r requirements.txt
如果系统中存在多个Python版本,更推荐:
Bashpython -m pip install -r requirements.txt
Linux环境也经常使用:
Bashpython3 -m pip install -r requirements.txt
这种方式可以减少pip与Python解释器对应错误的问题。
例如系统同时存在Python 3.10和Python 3.12时:
Bashpip install requests
不一定能够明确对应你当前使用的Python环境。
而:
Bashpython3.12 -m pip install requests
则明确使用Python 3.12对应的pip。
七、结合虚拟环境使用requirements
Python项目推荐使用虚拟环境,而不是直接向系统Python安装大量项目依赖。
创建虚拟环境:
Bashpython -m venv .venv
Windows激活:
Bash.venvScriptsctivate
Linux或macOS激活:
Bashsource .venv/bin/activate
激活后安装依赖:
Bashpython -m pip install -r requirements.txt
完成后,可以检查:
Bashpip list
这样项目之间的依赖就能够相互隔离。
例如:
项目A └── .venv └── Django 4.2 项目B └── .venv └── Django 5.1
两个项目可以使用不同版本的Django,而不会互相影响。
八、requirements文件中的注释和路径依赖
requirements文件不仅可以记录普通PyPI包,也支持注释。
例如:
# Web framework Django==5.1.2 # HTTP client requests==2.32.3
以#开头的内容通常作为注释处理。
还可以安装Git仓库中的项目,例如:
git+https://github.com/example/project.git
也可以指定分支:
git+https://github.com/example/project.git@develop
如果项目依赖本地目录,也可以使用类似:
-e ./my_package
-e表示以editable模式安装,适合项目开发阶段使用。
九、requirements.txt中如何处理不同环境
实际项目经常存在开发环境和生产环境依赖不同的问题。
例如生产环境只需要:
Django==5.1.2 gunicorn==23.0.0 psycopg==3.2.3
开发环境还需要:
pytest black ruff ipython
一种常见的组织方式是拆分文件:
requirements/ ├── base.txt ├── development.txt └── production.txt
base.txt:
Django==5.1.2 requests==2.32.3
development.txt:
-r base.txt pytest black ruff
production.txt:
-r base.txt gunicorn psycopg
开发环境执行:
Bashpip install -r requirements/development.txt
生产环境执行:
Bashpip install -r requirements/production.txt
这样能够避免把开发工具安装到生产服务器。
十、requirements.in与requirements.txt有什么区别
部分Python项目会同时出现:
requirements.in requirements.txt
两者用途并不完全相同。
requirements.in通常用于记录项目直接依赖,例如:
Django requests pandas
而requirements.txt可以进一步记录经过解析后的完整依赖及版本,例如:
Django==5.1.2 asgiref==3.8.1 sqlparse==0.5.1 requests==2.32.3 urllib3==2.2.3 certifi==2024.8.30
前者强调“项目直接需要什么”,后者更偏向“最终环境安装什么”。
这种模式通常会配合pip-tools使用,通过依赖解析生成锁定版本的requirements文件。
例如:
Bashpip-compile requirements.in
然后得到:
requirements.txt
安装时:
Bashpip-sync requirements.txt
对于需要较强环境可复现能力的项目,这种方式比单纯维护一个巨大的pip freeze结果更加清晰。
十一、requirements.txt如何升级依赖
升级某个指定包,可以直接执行:
Bashpip install --upgrade requests
然后查看当前版本:
Bashpip show requests
如果项目使用pip freeze维护requirements,可以重新生成:
Bashpip freeze > requirements.txt
不过重新生成前应该确认当前虚拟环境中没有安装大量与项目无关的软件包,否则可能把不需要的依赖一起写进去。
如果只想更新requirements中的某一个依赖,也可以手动修改:
requests==2.32.3
改为:
requests==2.33.0
然后重新执行:
Bashpip install -r requirements.txt
十二、如何检查requirements依赖是否存在冲突
安装依赖后,可以执行:
Bashpip check
如果没有问题,通常会显示:
No broken requirements found.
如果存在依赖冲突,则会提示具体的软件包和版本要求。
例如某个库要求:
urllib3<2
而当前环境却安装了:
urllib3 2.2.3
就可能导致兼容性问题。
出现这种情况时,不应该简单地强制安装某个版本,而应该检查依赖链,确认哪个软件包提出了版本限制。
还可以使用:
Bashpip show package_name
查看具体包的信息。
十三、requirements.txt常见错误
1. 找不到requirements.txt
执行:
Bashpip install -r requirements.txt
如果出现文件不存在,通常是当前目录不正确。
可以先执行:
Bashls
Linux/macOS查看目录内容,Windows可以使用:
cmddir
确认requirements文件实际位置。
如果文件位于config目录:
Bashpip install -r config/requirements.txt
2. Could not find a version that satisfies the requirement
例如:
ERROR: Could not find a version that satisfies the requirement xxx
可能原因包括:
-
包名称写错;
-
Python版本不兼容;
-
当前平台没有对应的预编译包;
-
指定的版本已经不存在或不可用;
-
pip版本过旧;
-
使用了无法访问的软件源。
可以先升级pip:
Bashpython -m pip install --upgrade pip
然后重新安装。
3. Permission denied
如果直接向系统Python安装依赖,可能遇到权限错误。
更推荐创建虚拟环境:
Bashpython -m venv .venv
然后在虚拟环境中执行:
Bashpython -m pip install -r requirements.txt
而不是长期依赖:
Bashsudo pip install -r requirements.txt
4. 版本冲突
例如requirements中同时出现:
packageA==1.0 packageB==2.0
而packageB依赖:
packageA>=2.0
就会产生无法满足的版本要求。
此时需要重新检查直接依赖和间接依赖,而不是盲目删除某一行。
十四、requirements.txt的最佳实践
使用虚拟环境
每个项目建立独立环境:
Bashpython -m venv .venv
避免多个项目共用系统Python环境。
生产项目尽量锁定版本
例如:
Django==5.1.2 requests==2.32.3
生产环境对稳定性要求较高,固定版本能够减少自动升级带来的不确定性。
开发和生产依赖分离
测试工具、代码格式化工具、调试工具没有必要全部进入生产环境。
可以采用:
requirements/base.txt requirements/development.txt requirements/production.txt
进行管理。
定期更新依赖
依赖长期不更新,可能积累安全漏洞和兼容性问题。
但升级时不要直接一次性更新所有软件包。更稳妥的方式是逐项升级、运行测试,再确认是否需要修改代码。
将requirements文件纳入版本控制
如果项目使用Git,应将:
requirements.txt
或者对应的requirements目录提交到代码仓库。
同时通常不需要提交:
.venv/
可以在.gitignore中添加:
.venv/ venv/ __pycache__/
十五、requirements.txt与pyproject.toml的关系
现代Python项目越来越多地使用pyproject.toml管理项目元数据和依赖。
例如:
TOML[project] name = "demo-project" version = "1.0.0" dependencies = [ "requests>=2.32", "Django>=5.1" ]
相比传统的requirements.txt,pyproject.toml能够承载更多项目级配置,包括项目名称、版本、构建系统以及依赖声明等。
不过,这并不意味着requirements.txt已经失去作用。
两种方式的定位并不完全相同:
| 文件 | 主要用途 |
|---|---|
| requirements.txt | 描述环境安装依赖 |
| requirements.in | 描述直接依赖并用于生成锁定文件 |
| pyproject.toml | Python项目元数据、依赖及构建配置 |
| uv.lock等锁定文件 | 记录更精确的解析结果 |
对于传统项目,requirements.txt依然简单、直观、兼容性好;对于新项目,则可以根据团队技术栈选择pyproject.toml以及相应的现代依赖管理工具。
十六、一个实用的requirements管理流程
一个相对规范的Python项目依赖管理流程可以归纳为:
创建虚拟环境 ↓ 安装项目需要的第三方库 ↓ 开发并测试项目 ↓ 整理直接依赖 ↓ 固定或约束关键版本 ↓ 生成requirements文件 ↓ 提交Git仓库 ↓ 其他环境创建虚拟环境 ↓ pip install -r requirements.txt ↓ 运行pip check和项目测试
如果项目规模较小,可以直接维护:
requirements.txt
项目规模扩大后,可以进一步采用:
requirements/ ├── base.txt ├── development.txt └── production.txt
或者:
requirements.in requirements.txt
通过分层管理降低依赖维护成本。
十七、一个完整示例
假设项目目录如下:
my-project/ ├── app/ │ ├── __init__.py │ └── main.py ├── requirements.txt ├── .gitignore └── README.md
requirements.txt内容:
Flask==3.0.3 requests==2.32.3 python-dotenv==1.0.1
新环境中执行:
Bashpython -m venv .venv
激活虚拟环境后:
Bashpython -m pip install --upgrade pip python -m pip install -r requirements.txt
检查依赖:
Bashpython -m pip check
查看安装结果:
Bashpython -m pip list
项目就可以在相对一致的Python环境中运行。
如果后续修改了依赖,应同步更新requirements文件,并通过Git提交变更,确保其他开发人员和部署环境使用相同的依赖描述。
对于Python项目而言,requirements文件解决的并不是“怎么安装一个库”这样简单的问题,而是如何让项目依赖清晰、可追踪、可复现。合理使用版本约束、虚拟环境、依赖分层和依赖检查,可以显著减少环境差异导致的问题。对于小型项目,规范维护requirements.txt已经足够;随着项目规模扩大,则可以逐步引入requirements.in、依赖锁定工具或pyproject.toml,建立更加完善的Python项目依赖管理体系。