0

0

依赖管理:requirements.txt 和 Pipenv/Poetry

紅蓮之龍

紅蓮之龍

发布时间:2025-09-06 12:56:01

|

293人浏览过

|

来源于php中文网

原创

Pipenv和Poetry通过自动化虚拟环境与锁文件机制解决依赖管理问题。1. 它们自动创建隔离环境,避免全局污染;2. 使用Pipfile.lock或poetry.lock锁定所有依赖精确版本,确保构建可复现;3. 内置依赖解析器减少版本冲突;4. 支持开发与生产依赖分离,提升团队协作效率。相较于requirements.txt的手动管理,二者提供更稳定、自动化和标准化的解决方案。

依赖管理:requirements.txt 和 pipenv/poetry

Python项目中的依赖管理,简单来说,就是确保你的代码能在一个稳定、可复现的环境中运行,不会因为依赖包的版本问题而“水土不服”。传统的

requirements.txt
固然直观,但面对复杂项目和团队协作时,它的局限性就显现出来了。这时候,Pipenv和Poetry这类工具的出现,提供了一站式的解决方案,它们不仅能管理依赖,还能隔离环境,让你的项目从开发到部署都更加顺畅、可控。

解决方案

依赖管理的核心在于确定项目所需的外部库及其精确版本,并确保这些库能够被正确安装和使用。

requirements.txt
的基础与局限

requirements.txt
是最简单直接的依赖管理方式。你用
pip freeze > requirements.txt
来生成当前环境的依赖列表,然后用
pip install -r requirements.txt
来安装。它的优点在于简单、易懂,几乎所有Python开发者都熟悉。

然而,它的局限性也很明显:

  1. 缺乏环境隔离
    requirements.txt
    本身不创建虚拟环境。你需要在项目根目录手动创建并激活虚拟环境(例如
    python -m venv .venv
    ),然后才能安全地安装依赖。这增加了手动操作的步骤,也容易出错。
  2. 非确定性安装
    requirements.txt
    默认只记录顶级依赖,不记录其子依赖(transitive dependencies)的精确版本。这意味着,如果一个顶级依赖的子依赖更新了,你的项目在不同时间或不同机器上安装时,可能会得到不同的子依赖版本,从而导致构建不一致甚至运行时错误。
  3. 依赖冲突解决弱:当项目中有多个顶级依赖,它们又各自依赖同一个库的不同版本时,
    pip
    很难智能地解决冲突。你可能需要手动调整版本,这非常耗时且容易出错。
  4. 开发与生产依赖混淆:通常,开发时我们可能需要一些测试工具、代码格式化工具,这些在生产环境中是不需要的。
    requirements.txt
    很难优雅地区分这些不同类型的依赖。

Pipenv:集成虚拟环境与确定性构建

Pipenv 的出现,就是为了解决

requirements.txt
的这些痛点。它将虚拟环境管理和依赖管理整合到一个工具中。

  • Pipfile
    Pipfile.lock
    :Pipenv 使用
    Pipfile
    来声明项目所需的顶级依赖,这比
    requirements.txt
    更具可读性。更关键的是,它会自动生成
    Pipfile.lock
    文件。这个
    lock
    文件会精确记录所有(包括子依赖)的哈希值和版本信息,确保每次安装都能得到完全相同的依赖集合,实现了确定性构建
  • 自动创建和管理虚拟环境:你不需要手动创建虚拟环境。
    pipenv install
    命令会自动为你的项目创建一个隔离的虚拟环境,并将依赖安装进去。
    pipenv shell
    可以激活这个环境。
  • 更好的依赖冲突解决:Pipenv 在解析依赖时,会尝试找到一个兼容所有声明依赖的版本组合,减少了手动干预。

Poetry:更现代的打包与依赖管理

Poetry 是一个更全面、更现代的Python项目管理工具,它不仅仅是依赖管理器,更是一个打包工具。

  • pyproject.toml
    :Poetry 遵循
    pyproject.toml
    标准(PEP 518/621),将项目元数据、依赖、构建配置等都统一到一个文件中。这让项目配置更加清晰和标准化。
  • poetry.lock
    :与 Pipenv 类似,Poetry 也使用
    poetry.lock
    文件来锁定所有依赖的精确版本,保证了环境的可复现性。
  • 集成打包与发布:Poetry 的一大亮点是其对包的构建和发布有原生支持。你可以用
    poetry build
    构建你的包,用
    poetry publish
    发布到 PyPI,整个流程非常顺畅。
  • 依赖组(Dependency Groups):Poetry 允许你定义不同的依赖组,比如
    dev
    (开发)、
    test
    (测试)等,可以按需安装,完美解决了开发与生产依赖分离的问题。

为什么传统的
requirements.txt
无法满足现代Python项目需求?

说实话,刚开始写Python的时候,

pip freeze > requirements.txt
简直是我的救星,简单粗暴又有效。但随着项目越来越复杂,团队协作越来越多,我发现这玩意儿的局限性简直是“一言难尽”。

一个明显的痛点就是环境隔离。如果你不手动创建虚拟环境,直接

pip install -r
,那所有依赖都会装到全局Python环境里,很快就变成一锅粥。不同项目依赖同一个库的不同版本,冲突是迟早的事。比如项目A需要
requests==2.20.0
,项目B需要
requests==2.28.0
,如果你都装在全局,那肯定有一个项目会出问题。手动管理虚拟环境又显得很繁琐,容易忘记激活,或者激活错了环境。

再者,考虑一下确定性构建

requirements.txt
默认只列出你直接依赖的包,至于这些包又依赖了哪些其他包(也就是所谓的“传递性依赖”),它是不管的。这意味着,即使你的
requirements.txt
文件内容不变,但如果某个传递性依赖在未来发布了新版本,你再次安装时就可能得到不同的依赖树。我记得有一次,我的一个项目在本地跑得好好的,部署到服务器上却总是报奇怪的错误,排查了半天,才发现是某个子依赖在服务器上安装了更新的版本,导致了不兼容。这种非确定性简直是噩梦。

另外一个角度看,依赖冲突的解决

requirements.txt
的世界里几乎全靠“人肉”。如果
flask
依赖
Werkzeug<2.1
,而
some-other-lib
依赖
Werkzeug>=2.2
pip
往往会直接报错或者安装一个不兼容的版本,然后你就得开始漫长的版本调试。这在大型项目中,简直是浪费生命。

最后,开发与生产依赖的分离也是一个头疼的问题。开发时我们可能需要

pytest
black
flake8
这些工具,但它们在生产环境是完全不必要的,甚至会增加部署包的大小。用
requirements.txt
的话,你可能需要维护
requirements_dev.txt
requirements_prod.txt
两个文件,手动同步和管理,这本身就是一件容易出错且低效的工作。这些都让我意识到,是时候寻找更智能的工具了。

Pipenv 和 Poetry 如何解决依赖冲突和环境隔离问题?

Pipenv 和 Poetry 在解决这些问题上,思路是相似的,但实现上各有侧重。它们的核心武器就是虚拟环境的自动化管理锁文件(lock file)机制

虚拟环境的自动化管理: 在我看来,这是它们最直观的优势。你不需要再手动

python -m venv .venv
,也不用担心忘记
source .venv/bin/activate
。当你在一个没有虚拟环境的项目目录中运行
pipenv install
poetry install
时,它们会自动检测并为你创建一个隔离的虚拟环境。这个环境通常会放在一个统一的位置(Pipenv 默认放在用户目录下的
.virtualenvs
,Poetry 默认放在项目根目录的
.venv
),并且工具会自动将你的项目依赖安装到这个专属环境里。

这意味着:

JTBC网站内容管理系统5.0.3.1
JTBC网站内容管理系统5.0.3.1

JTBC CMS(5.0) 是一款基于PHP和MySQL的内容管理系统原生全栈开发框架,开源协议为AGPLv3,没有任何附加条款。系统可以通过命令行一键安装,源码方面不基于任何第三方框架,不使用任何脚手架,仅依赖一些常见的第三方类库如图表组件等,您只需要了解最基本的前端知识就能很敏捷的进行二次开发,同时我们对于常见的前端功能做了Web Component方式的封装,即便是您仅了解HTML/CSS也

下载
  • 项目隔离:每个项目都有自己独立的依赖集合,互不干扰。项目A的
    requests
    版本不会影响项目B的
    requests
    版本。
  • 环境干净:你的全局Python环境保持整洁,避免了“依赖地狱”。
  • 操作简化:你只需要记住
    pipenv shell
    poetry shell
    就能进入环境,或者直接用
    pipenv run 
    /
    poetry run 
    来执行环境内的命令。

锁文件(

Pipfile.lock
poetry.lock
)机制
: 这是解决“非确定性安装”和“依赖冲突”的关键。当你在
Pipfile
pyproject.toml
中声明了顶级依赖后,
pipenv install
poetry install
会做几件事:

  1. 解析依赖树:它们会递归地找出你所有顶级依赖及其所有子依赖,构建出一个完整的依赖图。
  2. 解决冲突:在这个过程中,它们会尝试找到一个所有依赖都能兼容的版本组合。如果存在冲突,它们会尽力解决,或者给出明确的冲突提示。
  3. 生成锁文件:一旦找到一个可行的依赖组合,它们就会将这个组合中所有依赖(包括顶级和子依赖)的精确版本号和哈希值记录到
    Pipfile.lock
    poetry.lock
    文件中。

这个锁文件就是你的“依赖快照”。当你将项目提交到版本控制系统时,这个锁文件也应该被提交。这样,团队里的其他成员,或者你在另一台机器上,只需要运行

pipenv install
poetry install
,工具就会严格按照锁文件中记录的精确版本和哈希值来安装依赖。

这带来了巨大的好处:

  • 确定性构建:无论何时何地,只要有锁文件,你的依赖环境就永远是可复现的。彻底告别了“在我机器上跑得好好的”这种尴尬。
  • 减少冲突:虽然不能完全消除所有冲突(有些冲突可能根本无解),但它们在解析阶段就帮你做了大量工作,大大减少了手动解决冲突的频率。即使有冲突,锁文件也能帮助你快速定位问题。
  • 团队协作效率:团队成员之间可以共享同一个可复现的开发环境,减少了因环境差异导致的问题和沟通成本。

总的来说,Pipenv 和 Poetry 通过自动化虚拟环境和引入强大的锁文件机制,将依赖管理从一个手动、易错的过程,提升到了一个自动化、确定性、高效率的水平。

在什么场景下,我应该选择 Pipenv 还是 Poetry?

在我个人看来,选择 Pipenv 还是 Poetry,很大程度上取决于你的项目类型、团队偏好以及你对“一体化”工具的需求程度。这两个工具都比

requirements.txt
强大得多,但它们各自有擅长的领域和不同的哲学。

选择 Pipenv 的场景:

  • requirements.txt
    迁移,寻求更平滑的过渡
    :如果你和你的团队习惯了
    pip
    的工作流,Pipenv 会是一个非常好的起点。它的命令结构和
    pip
    有些相似,学习曲线相对平缓。它专注于解决虚拟环境和依赖锁的问题,不会引入太多额外的概念。
  • 简单的应用项目或脚本:对于那些不需要打包发布到 PyPI,只是内部使用或者部署到服务器的Web应用、数据分析脚本等,Pipenv 提供的功能已经足够强大。它能很好地处理依赖冲突和环境隔离,保持项目的整洁。
  • pyproject.toml
    尚未有强烈需求
    :Pipenv 使用
    Pipfile
    来管理依赖,这在当时是一个创新。如果你觉得
    pyproject.toml
    带来的额外配置有点多余,或者团队还没有全面拥抱它,Pipenv 是一个务实的选择。
  • 偏爱更轻量级的解决方案:相较于 Poetry,Pipenv 在功能上更聚焦于依赖管理和虚拟环境,没有集成打包、发布等高级功能,所以如果你不需要这些,它会显得更“轻量”。

选择 Poetry 的场景:

  • 开发需要发布到 PyPI 的库或包:这是 Poetry 最闪耀的领域。它从设计之初就考虑了包的构建、发布和元数据管理。使用
    pyproject.toml
    统一配置项目信息、依赖、构建系统,然后通过
    poetry build
    poetry publish
    一键完成发布,这个流程的顺畅度是 Pipenv 无法比拟的。我个人在开发开源库时,几乎都用 Poetry,因为它真的省去了很多配置
    setup.py
    的麻烦。
  • 追求现代、统一的项目配置标准:Poetry 拥抱了
    pyproject.toml
    标准,这代表了 Python 项目配置的未来趋势。如果你希望你的项目配置更加标准化、可维护,并且未来可能会将其他工具(如
    black
    ,
    isort
    ,
    pytest
    等)的配置也集成到
    pyproject.toml
    中,那么 Poetry 是一个更具前瞻性的选择。
  • 需要精细的依赖组管理:Poetry 的依赖组功能非常强大,可以清晰地区分开发依赖、测试依赖、文档依赖等。这对于大型项目或者有复杂开发流程的团队来说,非常有价值,可以按需安装,避免不必要的依赖膨胀。
  • 喜欢更严格、更一致的开发流程:Poetry 在很多方面都提供了更严格的规范和更一致的命令行体验。它的依赖解析算法通常被认为更健壮,能更好地处理复杂的依赖图。

我的个人倾向:

我个人倾向于 Poetry,尤其是在开发需要发布到PyPI的库时,它的集成度真的很高,省去了很多配置的麻烦。对于内部使用的Web服务或微服务,如果团队已经熟悉

pyproject.toml
的模式,我也更倾向于使用 Poetry,因为它能提供更一致的开发体验和更清晰的项目结构。但如果团队成员对新工具的接受度不高,或者项目非常简单,Pipenv 也是一个非常好的折中方案。选择哪个,最终还是要看项目实际需求和团队的舒适区。

requirements.txt
迁移到 Pipenv 或 Poetry 有哪些常见挑战?

requirements.txt
迁移到 Pipenv 或 Poetry,听起来是技术升级,但过程中确实会遇到一些小麻烦,这很正常。我经历过几次这样的迁移,总结了一些常见的“坑”和挑战。

一个最直接的问题就是如何导入现有的依赖。你可能已经有一个非常庞大的

requirements.txt
文件,里面包含了所有(包括子依赖)的精确版本。直接
pipenv install -r requirements.txt
或者
poetry add
导入,可能会导致一些意想不到的行为。

  • Pipenv
    pipenv install -r requirements.txt
    会尝试将
    requirements.txt
    中的所有依赖都添加到
    Pipfile
    中。如果你的
    requirements.txt
    pip freeze
    出来的,里面包含了大量的传递性依赖,那么
    Pipfile
    就会变得非常臃肿,失去了它作为“顶级依赖声明”的初衷。更好的做法是手动审查
    requirements.txt
    ,只把那些你直接用到的顶级依赖添加到
    Pipfile
    ,让 Pipenv 自己去解析和锁定子依赖。这需要一些人工判断和清理。
  • Poetry:Poetry 也有类似的问题。
    poetry add
    是逐个添加依赖的,如果你想批量导入,可能需要写脚本或者同样手动清理。一个常见的策略是,先创建一个空的
    pyproject.toml
    ,然后根据
    requirements.txt
    的内容,逐步添加顶级依赖。

第二个挑战是学习新的工作流程和命令。从

pip install
pip freeze
python -m venv
切换到
pipenv install
pipenv shell
pipenv run
,或者
poetry add
poetry install
poetry shell
,需要一个适应过程。团队成员可能需要花时间熟悉这些新命令,理解
Pipfile
/
Pipfile.lock
pyproject.toml
/
poetry.lock
的作用。一开始可能会有人忘记用
pipenv run
而直接
python app.py
,导致程序运行在全局环境而不是项目虚拟环境里。

再来,处理现有的虚拟环境。如果你的项目之前已经有了一个

.venv
目录,或者你习惯用
virtualenvwrapper
管理,那么 Pipenv 和 Poetry 在创建自己的虚拟环境时,可能会让你觉得有点混乱。Pipenv 默认会将虚拟环境放在一个全局位置,而 Poetry 默认放在项目根目录。这两种方式都需要团队成员明确知道,并且可能需要清理旧的虚拟环境,以避免混淆。

依赖解析的差异也可能带来惊喜。

pip
在解析依赖时,通常是“先到先得”或者“最新版本优先”,而 Pipenv 和 Poetry 有更复杂的解析算法,它们会尝试找到一个满足所有约束的兼容集。这意味着,即使你手动把
requirements.txt
里的依赖都添加到新的工具中,最终生成的
lock
文件里的版本号也可能和旧的
requirements.txt
不完全一致。这可能导致一些原本隐藏的依赖冲突浮出水面,需要你花时间去解决。

最后,CI/CD 流程的调整也是一个不可避免的环节。你的持续集成/持续部署脚本需要从

pip install -r
切换到
pipenv install --deploy
poetry install --no-dev
。这涉及到构建环境、缓存策略等方面的修改,需要测试确保新流程的顺畅运行。

这些挑战虽然存在,但一旦克服,新的依赖管理工具带来的效率提升和稳定性是显而易见的。这就像从手动挡汽车换到自动挡,一开始可能不习惯,但长远来看,驾驶体验会好很多。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

755

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

636

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

759

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

618

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1262

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

577

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

708

2023.08.11

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

2

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.7万人学习

MySQL 教程
MySQL 教程

共48课时 | 1.8万人学习

php-src源码分析探索
php-src源码分析探索

共6课时 | 0.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号