Pipenv 到底解决了什么问题?

2018-06-08 17:31:16 +08:00
 ifoolish

只是把 virtualenv 和 pip 结合成一个命令让使用更加方便?

区分开发与生产依赖?写两个不同的 requirements.txt 也可以区分啊。

那么 Pipenv 到底解决了 Python 包管理中的什么痛点?能否举个具体场景的栗子

7166 次点击
所在节点    Python
19 条回复
66450146
2018-06-08 17:45:25 +08:00
库版本更新啊,不搞一个单独的 .lock 文件更新一次依赖要掉一层皮
jennifertxwoodma
2018-06-08 17:49:11 +08:00
解决了不会敲 pip freeze >> requirements.txt 的人的痛点,
充分说明了技术界还是要会吹
fy
2018-06-08 17:55:30 +08:00
解决了 locking 太慢,python 程序员不能像大型 C/CPP 项目以等待构建为借口摸鱼的问题。
est
2018-06-08 18:00:05 +08:00
解决了 NIH 症状。
kunluanbudang
2018-06-08 18:07:38 +08:00
使用了一段时间,粉转黑了

😓
simpleapples
2018-06-08 18:15:01 +08:00
说一个平时时常用到的 pipenv shell 比 source venv/bin/activate 要方便很多
tonghuashuai
2018-06-08 18:25:07 +08:00
你的服务器上部署着三个 web 服务,第一个服务是你的前同事写的,需要 tornado 4.0.3,第二个服务是你写额,需要 tornado 4.3.0,第三个服务是你的另外一个同事写的,需要 tornado 5.0,只有一台服务器的情况下,就可以用 virtualenv 了
twor
2018-06-08 18:29:19 +08:00
@tonghuashuai virtualenv 不就是在同一台服务器解决这个问题的吗
doubleflower
2018-06-08 19:02:15 +08:00
@simpleapples 一个 alias 就解决的事用不着一个软件吧
chroming
2018-06-08 20:04:37 +08:00
方便且稳定就是进步了
0bit
2018-06-08 22:26:18 +08:00
就是 Python 的 npm
uranusjr
2018-06-08 22:35:35 +08:00
基於完整揭露原則:我是 Pipenv 三位目前的主要維護者,並同時維護其部份依賴。Pipenv 與 PyPA 並沒有嚴格組織,也不對維護者組成有任何約束,因此以下是我個人的觀點,無法代表 Python 官方意見。然而,我認為我的看法與 Python 核心社群的普遍共識一致。「 Pipenv 解決什麼問題」這個問題容易讓人落入邏輯誤區,因為 Pipenv 本質上包含了兩個不直接相關的部份:Pipfile 標準,以及 Virtualenv 操作。Pipenv 在兩個部份都試圖解決現有方案的問題,但是必須分開來看,才能正確評價它。

Pipfile 的目標是取代現在慣常使用的 requirements.txt 格式,並引入 lock file 概念(或者叫做 shrinkwrap )。這和 pip freeze 最大的差異是,lock file 是一個理論上的依賴視圖,而 pip freeze 是產生實際上的依賴視圖。當你使用 pip freeze 時,只是單純將已經安裝的套件狀況「倒」出來。當你觸發 locking 行為時,則是會直接取用套件的 metadata,直接建立套件的依賴結果。這在理論上是個沒有副作用的行為(當然實際上套件在編譯期有什麼副作用是完全未知的,這沒有辦法),所以只要依賴本身沒有改變(例如沒有更新),每次 locking 的行為應該完全相同。這在依賴解析上是重要的特性,有興趣的人可以自行研究,這裡不贅述。

上面的說法可能會讓你認為 Pipfile 的進步點在於一個更好的依賴解析格式與行為,但其實不是如此。它提供的是依賴解析這件事情「本身」——因為這個概念在 pip 中根本不存在。考慮以下的狀況:你的專案使用了套件 A 套件,它依賴於套件 B 的 2.x 系列。你的 requirements.txt 可能會長這樣:

A==1.0
B==2.5.1

現在你想要實作新功能,而加入套件 C,而它依賴 B 套件 3.0 的 API。在使用 pip 的狀況下,你會 pip install C。由於 pip 本身並沒有依賴解析功能,它只知道要安裝 C,以及其依賴 B 3.0,於是你的 freeze 結果變成這樣:

A==1.0
B==3.0.0
C==1.0

這時候 A 很可能無法使用,而你也已經失去了前一個狀態,必須重新建立你的開發環境。但是更可能的是,如果你沒有完整的測試機制,說不定完全不會發現這件事情,直到有人抱怨。

另一方面,由於 Pipfile 擁有獨立的解析步驟,且不需要先將套件實際安裝至環境中,當你將 C 加入 Pipfile 時,locking 就會直接告知你這個依賴無法被解析,防止後面的所有問題。並且由於它只有在解析成功時,才會進行安裝,你只要把 C 從 Pipfile 移除,即可回到原本的專案狀態。

基於同樣的理由,Pipfile 同時也有一些其他好處。如果你有平台專屬的依賴,例如 Windows 使用 X 套件,在 Mac 使用 Y,然後寫一個抽象層之類的需求,pip freeze 基本無法處理。Pipfile 因為不需要把套件本身裝到環境中,就可以處理這個狀況。

在 Pipfile 之前,也有其他類似功用的專案,只是沒有提出全新的格式,而是沿用 requirements.txt 。piptools 是一個比較有名的實例。不過 Pipfile 的 TOML 格式與 lock file 的 JSON 格式比起基於行的純文字 requirements.txt 遠遠更有表達能力,能夠處理更廣泛的使用情境。

回到 Pipenv,在虛擬環境的使用上,它的創新度就遠沒有 Pipfile 格式那麼高,只是一個 virtualenv 的殼,唯一比較值得一提的,只有 run 與 shell 這兩個指令。Shell 前面有人已經提到,比起 activate 要方便一些,因為後者是直接修改你現有的 shell 環境,而 shell 是直接啟動一個 shell 子程序,所以跑起來更乾淨,也不容易出錯。不過這年頭 terminal emulator 滿街跑,這也有很多其他 workaround 做法,shell 充其量就是推廣這樣的 best practice 讓更多人知道。Run 也是差不多,其實就是自動幫你 active-執行指令-deactivate。非常方便,但沒有特別解決什麼問題。

如果你問 Pipenv 解決了什麼問題,對我而言,Pipfile 格式與它提供的 locking 才是重點,虛擬環境管理我自己寫一個也不費什麼力氣(我加入 Pipenv 之前就寫過,現在還是有自己寫),其實沒什麼。但是對 Pipenv 使用者而言,每天用到的都是虛擬環境的介面,套件管理根本用不到個幾次,更難注意到它的技術細節差異,所以單純看它的虛擬環境指令,覺得好像可有可無也是合情合理,我們維護者也都很清楚,所以我們最近(大約是從今年 PyCon US 起,到現在大約一個月)努力的方向,就是盡可能把 Pipenv 的各個組件拆分成獨立的套件,並鼓勵大家根據這些套件建構自己的工具,讓這些技術能夠正確地被評價。

Pipenv 的初始作者是 Kenneth Reitz,我想大家都很清楚。Kenneth 最突出的技能,是為一個工作流程設計流暢、實用、完整的介面,如果你有密切關注他過往的專案,例如 Requests 與 Records,應該能夠很明顯察覺。然而在設計流暢介面時,有時候就免不了犧牲技術上的純粹性:Requests 的 json() 函式與 Records 的 Pandas 整合都是十分明顯的例子。在這兩個專案中,HTTP 與 SQL 基本都是應用相當成熟的應用,所以大家也比較能夠準確評價這些功能的,以及函式庫的定位,但套件管理在 Python 社群,甚至整個程式社群中,就不是那麼普遍的知識,因此當你把很多個技術混在一起時,大家就很難準確評價最終成果。這有點令人遺憾,不過也是我們接下來最重要的努力目標。希望這樣的解釋能夠讓大家更理解套件管理與依賴解析,進而能夠理解,甚至協助建立 Pipenv 的正確定位。
wenbinwu
2018-06-08 22:37:46 +08:00
@uranusjr 先回复再拜读
SuperMild
2018-06-08 22:54:00 +08:00
@uranusjr 高质量内容!
laike9m
2018-06-08 23:25:15 +08:00
@uranusjr 怎么看 Poetry 作者指出的 pipenv 解析依赖可能不成功的问题 ?
https://github.com/sdispater/poetry#what-about-pipenv
ifoolish
2018-06-08 23:36:38 +08:00
@uranusjr #12 感谢你的耐心回复。而且终于见到了个具体的例子。但是如你所说的例子,即 Pipfile.lock 还是无法解决 A 和 C 依赖 B 的不同版本的问题吗?只是检测到依赖冲突后做出提示并阻止安装而已?
uranusjr
2018-06-08 23:43:24 +08:00
@laike9m 解析依賴本來就有很多能出錯的地方,Poetry 的依賴解析也會莫名的不成功,我覺得有空吵這個不如大家努力來找 bug 修復它。前面提到的組件獨立工作也有部分考量到這個問題,如果能夠把解析組件獨立出來,各工具就能夠自行插拔組合出合適的介面,不用像 Pipenv 與 Poetry 各自重新造輪子,各有各的問題,卻無法互相協助。應外 Python 依賴解析有個硬傷是套件資訊過於混亂,setup.py 是可怕的歷史錯誤,Pipenv 目前 locking 極慢有部份也是這個因素(雖然還有優化空間,我們目前有一些方向,希望這幾個月能夠再改善)。
uranusjr
2018-06-08 23:47:19 +08:00
@ifoolish 以 Python 目前的設計確實就是無法解決了,只能阻止安裝。核心開發者有提出一些方案,不過還沒有明確結論,實作上也不容易。如果有相關知識,尤其對於不同依賴版本有解法的工具(如 Bundler 與 NPM )經驗者,歡迎到 Python 的 SIG mailing lists 參與討論,我們很需要專業知識的協助。
dcoder
2018-10-22 15:38:03 +08:00
@uranusjr @ifoolish
我就问个最简单粗暴的问题, 在大多数时候, pipenv 到底能不能完美地复制一个开发环境?
比如我用 Mac 在本地做完了开发, 想 deploy 到 AWS, 用 Pipfile.lock 就能完美复制本地环境,
保证无错地在 AWS 的 Linux server 上跑起来么? 哪种情况下会出错, 是 pipenv 用户需要避免的?

另外, 假设我每次在本地 Mac 更新开发配置, 有没有 reliable 的流程 push 更新到我 AWS server 上?
如果可以的话,就可以用 pipenv 来做自动部署了. 有没有人这么做? 一定程度代替 docker?

从 pipenv 官网上看, 其设计思路是, 要查看被依赖包的 hash 的, 类似 Nix ( https://nixos.org/nix/)
所以它解决的问题,应该是可靠地 produce deterministic builds 环境.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/461581

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX