一、起因

最近在逛一些当下比拟热的python开源代码(fastapi、langchain、redash)的时候,发现我的项目根目录都很难见到requirments.txt这个包依赖文件了,取而代之的是pyproject.toml文件和poetry.lock文件。而我,还只会应用requirments.txt,来自程序员的直觉是,我曾经掉队了,不由得一阵危机感,随之而来的是几个问题:

  1. pyproject.toml和poetry.lock这两个文件到底是啥?
  2. 为啥一线的开源我的项目都曾经弃用requirments.txt?
  3. pyproject.toml和poetry.lock好在哪?

去python官网逛了一下,发现了 PEP518标准,是这么说的:

The build system dependencies will be stored in a file named pyproject.toml that is written in the TOML format
  • pyproject.toml是python官网举荐的新标准,用于形容python我的项目的依赖,取代了之前的requirments.txt,一个pyproject.toml文件大抵长这样

    • 蕴含了代码库名称、版本、lisence等meta信息,还有python版本、依赖包的版本等信息,比原来干瘪瘪的requirments.txt是要丰盛不少
  • poetry.lock则是用于治理python我的项目依赖关系的工具Poetry生成的文件。 它记录了我的项目所依赖的包的版本信息,帮忙开发者在不同的开发环境中放弃依赖的一致性,一个poetry.lock文件大抵长这样

    • 形容了依赖包的版本、环境,以及依赖包的子依赖包的版本,甚至准确到了哈希值

那么这个Poetry是何方神圣,竟然受到泛滥一线开源我的项目的青眼,应该不是花瓶,探一探到底先。

于是照着Poetry官网文档操作了一波之后, 不禁感叹:这才是正经的包治理!

二、Poetry VS 传统包治理

1、主动生成、治理可能残缺形容我的项目依赖的toml文件

  • 传统包治理

    • 以往常常会遇到一类状况,拿到一个我的项目,依据requirements.txt装置依赖的时候,因为requirements.txt不足对python版本的形容,导致接手的人不晓得python版本
    • 之前有个我的项目是基于python3.8开发的,我选了过后还算比拟新的python3.6,装置requirements.txt,而后运行报错,排查之后才发现是python版本不统一导致的问题
  • Poetry

    • 能解决以上问题,它会主动生成并治理pyproject.toml文件,生成代码库名称、版本、lisence等meta信息,还有python版本、依赖包的版本等信息

2、为生产和开发环境提供独自的依赖

  • 传统包治理

    • 一个场景是,开发、测试环境须要的包,生产环境不肯定须要,比方pytest、flake8、black、pycodestyle等等,传统的做法是,建设多个requirements.txt,比方:requirements-dev.txt、requirements-test.txt、requirements-pro.txt,这样文件繁多,不利于对立治理
  • Poetry

    • 能够把所有环境的依赖比拟好地区分,都放入pyproject.toml文件中对立治理

3、更新包版本,主动在pyproject.toml中同步更新

  • 传统包治理

    • 传统工具pip或者conda在更新或者增加包之后,须要手动或者pip freeze一下依赖,频繁更新容易遗记
  • Poetry

    • 将这个过程合二为一,只须要poetry add XXX,依赖信息会自动更新到pyproject.toml

4、依赖关系的解决

  • 传统包治理

    • 应用pip治理依赖比拟大的一个痛点场景是,装置pandas==2.0.2,须要依赖numpy>=1.20.3,而后,你又装置了numpy==1.20.2,只管产生了依赖抵触,pip仍然会将numpy版本更新到1.20.2(与pandas==2.0.2对于numpy版本的要求抵触),这样,默默地引入依赖抵触的包,会在后续的程序运行中导致潜在的抵触问题,而且不太好排查解决。
  • Poetry

    • 会立刻报错,并提醒正当的版本区间

5、彻底删除已有依赖包以及子依赖包

  • 传统包治理

    • 应用pip治理依赖另一个比拟大的痛点场景是,比方装置pandas==2.0.2的时候,顺带装置了包含numpy>=1.20.3在内的数十个子依赖,当你想要卸载pandas的时候,pip uninstall pandas,只会卸载pandas自身,而不会去卸载其下的数十个子依赖包,导致的问题就是,呈现大量不会应用到的【孤儿】子依赖包,长此以往,包占用的空间【虚胖】,节约存储空间,包治理也一团糟。
  • Poetry

    • 能够很好地治理依赖以及子依赖,删除依赖包的同时,一并删除子依赖,保护一个洁净高效的我的项目环境。

三、总结

Poetry提供了比pip和conda更多的劣势

  1. 统一的软件包装置:Poetry提供了一个统一的格局来装置任何软件包,确保整个我的项目有一个标准化的办法。
  2. 高效的依赖性治理:Poetry只为指定的软件包装置必要的依赖性,缩小你环境中不相干的软件包的数量。
  3. 简化的软件包移除:Poetry简化了软件包及其相干依赖关系的移除,使其易于保护一个洁净和高效的我的项目环境。
  4. 依赖性解决:Poetry的确定性解析器无效地解决了依赖关系,及时辨认并解决任何不统一或抵触。

尽管Poetry可能须要团队成员破费一些额定的工夫和精力来学习和适应,但从久远来看,应用Poetry这样的工具能够为你节省时间和精力。

给所有python开发安利这款神器。

四、号外

  • 看看隔壁,java(gradle.build)、前端开发(package.json),早都曾经用上了现代化的包管理工具及标准,不得不感叹,python在机器学习、深度学习上的确拿捏了,但在工程化这方面,还是落后于他人家的小孩不止一点半点,工程化比拟拉胯的另一个例子是,python直到最近一两年,随着fastapi的推广,才大范畴用上swagger,极大地促成了接口开发联调效率,用过之后,不得不说,真香。