V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
ifoolish
V2EX  ›  Python

Pipenv 到底解决了什么问题?

  •  
  •   ifoolish · 2018-06-08 17:31:16 +08:00 · 7165 次点击
    这是一个创建于 2354 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    第 1 条附言  ·  2018-06-09 01:02:02 +08:00

    下面一位 Pipenv 维护者的回复让我了解到了一件事,虽然 node 社区里大家都吐槽 npm 的依赖目录树设计导致了 node_modules 目录过深多大的问题,但是 npm 的这个设计解决了多个包依赖同一个包的不同版本的问题。而这是目前 Python 的包管理尚未做到的事 :doge

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

    😓
    simpleapples
        6
    simpleapples  
       2018-06-08 18:15:01 +08:00
    说一个平时时常用到的 pipenv shell 比 source venv/bin/activate 要方便很多
    tonghuashuai
        7
    tonghuashuai  
       2018-06-08 18:25:07 +08:00
    你的服务器上部署着三个 web 服务,第一个服务是你的前同事写的,需要 tornado 4.0.3,第二个服务是你写额,需要 tornado 4.3.0,第三个服务是你的另外一个同事写的,需要 tornado 5.0,只有一台服务器的情况下,就可以用 virtualenv 了
    twor
        8
    twor  
       2018-06-08 18:29:19 +08:00
    @tonghuashuai virtualenv 不就是在同一台服务器解决这个问题的吗
    doubleflower
        9
    doubleflower  
       2018-06-08 19:02:15 +08:00
    @simpleapples 一个 alias 就解决的事用不着一个软件吧
    chroming
        10
    chroming  
       2018-06-08 20:04:37 +08:00
    方便且稳定就是进步了
    0bit
        11
    0bit  
       2018-06-08 22:26:18 +08:00
    就是 Python 的 npm
    uranusjr
        12
    uranusjr  
       2018-06-08 22:35:35 +08:00   ❤️ 23
    基於完整揭露原則:我是 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
        13
    wenbinwu  
       2018-06-08 22:37:46 +08:00
    @uranusjr 先回复再拜读
    SuperMild
        14
    SuperMild  
       2018-06-08 22:54:00 +08:00
    @uranusjr 高质量内容!
    laike9m
        15
    laike9m  
       2018-06-08 23:25:15 +08:00
    @uranusjr 怎么看 Poetry 作者指出的 pipenv 解析依赖可能不成功的问题 ?
    https://github.com/sdispater/poetry#what-about-pipenv
    ifoolish
        16
    ifoolish  
    OP
       2018-06-08 23:36:38 +08:00
    @uranusjr #12 感谢你的耐心回复。而且终于见到了个具体的例子。但是如你所说的例子,即 Pipfile.lock 还是无法解决 A 和 C 依赖 B 的不同版本的问题吗?只是检测到依赖冲突后做出提示并阻止安装而已?
    uranusjr
        17
    uranusjr  
       2018-06-08 23:43:24 +08:00
    @laike9m 解析依賴本來就有很多能出錯的地方,Poetry 的依賴解析也會莫名的不成功,我覺得有空吵這個不如大家努力來找 bug 修復它。前面提到的組件獨立工作也有部分考量到這個問題,如果能夠把解析組件獨立出來,各工具就能夠自行插拔組合出合適的介面,不用像 Pipenv 與 Poetry 各自重新造輪子,各有各的問題,卻無法互相協助。應外 Python 依賴解析有個硬傷是套件資訊過於混亂,setup.py 是可怕的歷史錯誤,Pipenv 目前 locking 極慢有部份也是這個因素(雖然還有優化空間,我們目前有一些方向,希望這幾個月能夠再改善)。
    uranusjr
        18
    uranusjr  
       2018-06-08 23:47:19 +08:00
    @ifoolish 以 Python 目前的設計確實就是無法解決了,只能阻止安裝。核心開發者有提出一些方案,不過還沒有明確結論,實作上也不容易。如果有相關知識,尤其對於不同依賴版本有解法的工具(如 Bundler 與 NPM )經驗者,歡迎到 Python 的 SIG mailing lists 參與討論,我們很需要專業知識的協助。
    dcoder
        19
    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 环境.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2661 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:26 · PVG 23:26 · LAX 07:26 · JFK 10:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.