一、起因
最近在逛一些當下比較熱的python開源代碼(fastapi、langchain、redash)的時候,發現項目根目錄都很難見到requirments.txt這個包依賴文件了,取而代之的是pyproject.toml文件和poetry.lock文件。而我,還只會使用requirments.txt,來自程序員的直覺是,我已經落伍了,不由得一陣危機感,隨之而來的是幾個問題:
- pyproject.toml和poetry.lock這兩個文件到底是啥?
- 為啥一線的開源項目都已經棄用requirments.txt?
- 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更多的優勢
- 一致的軟件包安裝:Poetry提供了一個一致的格式來安裝任何軟件包,確保整個項目有一個標準化的方法。
- 高效的依賴性管理:Poetry只為指定的軟件包安裝必要的依賴性,減少你環境中不相干的軟件包的數量。
- 簡化的軟件包移除:Poetry簡化了軟件包及其相關依賴關係的移除,使其易於維護一個乾淨和高效的項目環境。
- 依賴性解決:Poetry的確定性解析器有效地解決了依賴關係,及時識別並處理任何不一致或衝突。
雖然Poetry可能需要團隊成員花費一些額外的時間和精力來學習和適應,但從長遠來看,使用Poetry這樣的工具可以為你節省時間和精力。
給所有python開發安利這款神器。
四、號外
- 看看隔壁,java(gradle.build)、前端開發(package.json),早都已經用上了現代化的包管理工具及規範,不得不感嘆,python在機器學習、深度學習上確實拿捏了,但在工程化這方面,還是落後於別人家的小孩不止一點半點,工程化比較拉胯的另一個例子是,python直到最近一兩年,隨着fastapi的推廣,才大範圍用上swagger,極大地促進了接口開發聯調效率,用過之後,不得不説,真香。