相比 Pipenv,Poetry 是一個更好的選擇

前情提要

Pipenv 描繪了一個好夢,讓咱們覺得 Python 也有了其餘語言那樣完善的包管理器,不過這一切卻在後來者 Poetry 這裏獲得了更好的實現。python

這幾年 Pipenv 收穫了不少用戶,可是也暴露了不少問題。雖然 Lock 太慢、Windows 支持很差和 bug 太多的問題都已經改進了不少,但對我來講,仍然不能接受隨時更新鎖定依賴的設定,在上一篇文章《不要用 Pipenv》裏也吐槽了不少相關的問題。git

在這篇文章裏,我會介紹一個看起來和事實上都更靠譜的 Python 虛擬環境和依賴管理工具 Poetry,做者是 Sébastien Eustace。這是一個新的坑嗎?我想並非,儘管這是一個更年輕的工具,1.0 尚未發佈,也存在各類各樣的 bug,但至少基本使用流程沒有問題,用法設計也符合直覺。github

Poetry 是什麼

Poetry 和 Pipenv 相似,是一個 Python 虛擬環境和依賴管理工具,另外它還提供了包管理功能,好比打包和發佈。你能夠把它看作是 Pipenv 和 Flit 這些工具的超集。它可讓你用 Poetry 來同時管理 Python 庫和 Python 程序。shell

安裝 Poetry

官方推薦的安裝命令是使用自帶的 get-poetry.py 腳本,使用 curl:flask

$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python複製代碼

或者直接下載這個安裝腳本 get-poetry.py,而後在本地執行。bash

由於這個命令在安裝時會從 GitHub 下載一個 7M 的壓縮包,若是不用代理某些地區可能會很慢。實際測試使用代理安裝耗時約 30 秒,不用代理等了 5 分鐘,而後鏈接被重置。app

若是沒有用代理,能夠用 pip 安裝(不過 Poetry 官方文檔不建議這麼作,由於有可能會形成依賴衝突,能夠考慮用 pipxpipsi):curl

$ pip install --user poetry複製代碼

安裝後可使用下面的命令確認安裝成功:工具

$ poetry --version
Poetry 0.12.17複製代碼

若是報錯,能夠試試從新建立一個命令行會話。學習

附註 在 Mac 上安裝報錯 ~/.bash_profile 權限錯誤,臨時沒管,也能正常運行。後續能夠考慮手動把 ~/.poetry/bin 加進去。

Poetry 的基本用法

Poetry 的用法很簡單,大部分命令和 Pipenv 接近。咱們須要先了解一些基本概念和 Tips:

  • 使用 PEP 518 引入的新標準 pyproject.toml 文件管理依賴列表和項目的各類 meta 信息,用來替代 Pipfile、requirements.txt、setup.py、setup.cfg、MANIFEST.in 等等各類配置文件。
  • 依賴分爲兩種,普通依賴(生產環境)和開發依賴。
  • 安裝某個包,會在 pyproject.toml 文件中默認使用 upper bound(中文翻譯?)版本限定,好比 Flask^1.1。這被叫作 Caret requirements(中文翻譯?),好比某個依賴的版本限定是 ^2.9.0,當你執行 poetry update 的時候,它或許會更新到 2.14.0,但不會更新到 3.0.0;假如固定的版本是 ^0.1.11,它可能會更新到 0.1.19,但不會更新到 0.2.0。總之,在更新依賴的時候不會修改最左邊非零的數字號版本(對於 SemVer 版本號而言),這樣的默認設定能夠確保你在更新依賴的時候不會更新到具備不兼容變更的版本。另外也支持更多依賴版本限定符號
  • 不會像 Pipenv 那樣隨時更新你的鎖定依賴版本,鎖定依賴存儲在 poetry.lock 文件裏(這個文件會自動生成)。因此,記得把你的 poetry.lock 文件歸入版本控制。
  • 執行 poetry 或 poetry list 命令查看全部可用的命令。

若是你想了解更多進階的內容,好比設置命令行補全、打包和發佈等等,請閱讀 Poetry 文檔

準備工做

若是你是在一個已有的項目裏使用 Poetry,你只須要執行 poetry init 命令來建立一個 pyproject.toml 文件:

$ poetry init複製代碼

根據它的提示輸入你的項目信息,不肯定的內容就按下 Enter 使用默認值,後續也能夠手動更新。指定依賴的環節能夠跳過,手動安裝會更高效一點。

若是你想建立一個新的 Python 項目,使用 poetry new <文件夾名稱> 命令能夠建立一個項目模板:

$ poetry new foo複製代碼

這會建立一個這樣的項目結構:

foo
├── pyproject.toml
├── README.rst
├── foo
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_foo.py複製代碼

若是你想使用 src 文件夾,能夠添加 --src 選項,這會把程序包嵌套在 src 文件夾裏。

建立虛擬環境

使用 poetry install 命令建立虛擬環境(確保當前目錄有 pyproject.toml 文件):

$ poetry install複製代碼

這個命令會讀取 pyproject.toml 中的全部依賴(包括開發依賴)並安裝,若是不想安裝開發依賴,能夠附加 --no-dev 選項。若是項目根目錄有 poetry.lock 文件,會安裝這個文件中列出的鎖定版本的依賴。若是執行 add/remove 命令的時候沒有檢測到虛擬環境,也會爲當前目錄自動建立虛擬環境。

激活虛擬環境

執行 poetry 開頭的命令並不須要激活虛擬環境,由於它會自動檢測到當前虛擬環境。若是你想快速在當前目錄對應的虛擬環境中執行命令,可使用 poetry run <你的命令> 命令,好比:

$ poetry run python app.py複製代碼

若是你想顯式的激活虛擬環境,使用 poetry shell 命令:

$ poetry shell複製代碼

安裝包

使用 poetry add 命令來安裝一個包:

$ poetry add flask複製代碼

添加 --dev 參數能夠指定爲開發依賴:

$ poetry add pytest --dev複製代碼

追蹤 & 更新包

使用 poetry show 命令能夠查看全部安裝的依賴(能夠傳遞包名稱做爲參數查看具體某個包的信息):

$ poetry show複製代碼

添加 --tree 選項能夠查看依賴關係:

$ poetry show --tree複製代碼

添加 --outdated 能夠查看能夠更新的依賴:

$ poetry show --outdated複製代碼

執行 poetry update 命令能夠更新全部鎖定版本的依賴:

$ poetry update複製代碼

若是你想更新某個指定的依賴,傳遞包名做爲參數:

$ poetry update foo複製代碼

卸載包

使用 poetry remove <包名稱> 卸載一個包:

$ poetry remove foo複製代碼

經常使用配置

Poetry 的配置存儲在單獨的文件中,比 Pipenv 設置環境變量的方式要方便一點。配置經過 poetry config 命令設置,好比下面的命令能夠寫入 PyPI 的帳號密碼信息:

$ poetry config http-basic.pypi username password複製代碼

下面的命令設置在項目內建立虛擬環境文件夾:

$ poetry config settings.virtualenvs.in-project true複製代碼

另外一個經常使用的配置是設置 PyPI 鏡像源,以使用豆瓣提供的 PyPI 鏡像源爲例,你須要在 pyproject.toml 文件里加入這部份內容:

[[tool.poetry.source]]
name = "douban"
url = "https://pypi.doubanio.com/simple/"複製代碼

不過通過測試 Poetry 會使用 pip.ini 設置的 PyPI 鏡像,並且豆瓣的源好像好久沒更新了(建立虛擬環境安裝的默認依賴裏 importlib-metadata==0.20 找不到),這篇文章列出了一些其餘國內的 PyPI 源。

總結

總的來講,我願意深刻嘗試和使用 Poetry。固然,通過使用 Pipenv 的痛苦經歷,我對推薦工具這種事情變得更保守了。因此我不推薦 Python 初學者使用,不推薦直接在生產環境使用,不推薦無法正常訪問國際互聯網的人使用。

列一些我瞭解到的優缺點:

優勢

  • 使用標準的 pyproject.toml 標準,不用寫多個配置文件
  • 同時支持管理 Python 程序和 Python 庫
  • 更符合直覺的默認設計,好比不會隨便更新鎖定版本的依賴
  • 乾淨簡潔的命令行輸出,沒有星星和蛋糕
  • 安裝包的時候,使用 upper bound 版本限定,而不是 Pipenv 默認的通配符
  • 卸載包的時候,直接卸載孤立的子依賴,不須要像 Pipenv 那樣須要再執行 pipenv clean

缺點

  • 「poetry」這個單詞有一點難打……
  • 引入新的 pyproject.toml 標準,舊項目須要一點遷移成本和學習成本
  • 會有一些潛在的 bug
  • 解析依賴的過程偶爾會久一點
  • 對虛擬環境的管理控制有些弱,沒有 Pipenv 那樣的刪除虛擬環境和清空依賴的操做
  • 缺乏一個穩定的維護團隊,有大量 issue 和 PR 等待處理,但狀況在逐漸好轉

固然,你仍是能夠選擇繼續使用 virtualenv 和 pip 這些基礎工具,直到有一個完美的解決方案出現。或者,也能夠選擇試試新東西,而後嘗試改進它,讓完美的解決方案早一點出現。

(2)


原標題是「相比 Pipenv,Poetry 是一個更好的選擇嗎?」

相關文章
相關標籤/搜索