Python 套件管理器——Poetry 完全入門指南
文章目錄
by Feifei Ruan on Behance
2025/05/24
:更新系列第三篇——〈Docker 教學:用 Multi-stage build 建立 Poetry 虛擬環境〉。2025/05/23
:持續為全文減肥,提高可讀性。2025/05/11
:將「pip 的最大不足」大部分內容移至 Notion 頁面。2024/06/17
:縮減本文篇幅,方便讀者回顧,將「pip 替代方案選擇——Pipenv vs Poetry」部分移至 Notion 頁面。
前陣子工作上的專案從原先的 pip 改用 Poetry 管理 Python 套件,拜這個機會所賜,我對 Poetry 總算有了一個較為全面的理解。
對於 Poetry 這個略嫌複雜的工具(相較 pip),上手的同時我也感受到它確實存在一些學習門檻,間接促使了本文的誕生。
系列:Python Poetry 三部曲
- Python 套件管理器——Poetry 完全入門指南
- Poetry + pyenv 教學:常用指令與注意事項
- Docker 教學:用 Multi-stage build 建立 Poetry 虛擬環境
本文定位:獻給 Poetry 新手的使用說明書
有鑑於 Poetry 真的有點複雜,如果要推薦別人使用,我想還是有必要好好介紹一下。換句話說,這會是一篇完整的入門教學。
本文除了講解如何使用 Poetry,還會先不厭其煩地闡述它所解決的痛點,如果興趣有限,可以直接跳到「從零開始使用 Poetry」章節。
範例 repository
想要善用 Poetry,除了必須了解 Poetry 指令,熟悉pyproject.toml
檔案的設定也很重要。
有關 Poetry 的pyproject.toml
具體內容,可以參考這個範例專案:Django-Tutorial 中的pyproject.toml
;或直接前往檔案網址。
本文目錄
方便快速跳轉到有興趣的部分,桌面版用戶可和右下角的「回到最上方」搭配使用:
- Poetry 是什麼?
- 名詞解釋
- pip 的最大不足
- 安裝 Poetry
- 設定 PATH 環境變數
- 初始化 Poetry
- 管理 Poetry 虛擬環境
- 修改 config,建立專案內 .venv 虛擬環境
- Poetry 新增套件
- 指定套件「版本」範圍
- 新增套件至 dev-dependencies
- Poetry 更新套件
- 列出全部套件清單
- Poetry 移除套件
- 輸出 Poetry 虛擬環境的 requirements.txt
- Poetry 常用指令清單
- Poetry 常見使用情境與操作 QA
- 結語:井然有序的複雜
Poetry 是什麼?
要了解 Poetry 大致的作用與功能,參考 Poetry GitHub 說明是一個不錯的開始:
Poetry: Dependency Management for Python
Poetry helps you declare, manage and install dependencies of Python projects
而 Poetry 官網的 slogan 則更加簡潔有力:
python-poetry.org
簡單來說,Poetry 類似 pip,能協助你進行套件管理(dependency management),但又比 pip 強大得多,因為它還包含了 pip 所未有的下列功能:
- 虛擬環境管理
- 套件相依性管理
- 套件的打包與發布
其中最為關鍵的是「套件的相依性管理」,也是本文的重點,而「套件的打包與發布」與本文主題無關,所以不會提及。
名詞解釋
為了避免混淆,先說明以下概念。
虛擬環境管理
使用 venv 或 virtualenv 等工具,建立獨立的 Python 環境,不同環境間的套件互不影響。
套件管理(dependency management)
使用 pip 等工具,新增、刪除,管理 Python 環境中的所有套件及其版本。
套件的「相依性管理」(重要)
管理套件之間的依賴關係和版本衝突,確保專案的穩定性。
Poetry 的主要目標,正是解決 pip 在相依性管理上的不足。
pip 的最大不足
2025/05/11
:為縮減篇幅、方便讀者回顧,我將關於 pip 相依性管理缺陷的背景與實例細節,移至 Notion 頁面。
簡言之,直接 pip 手動移除依賴套件存在下列兩大疑慮,不建議輕易嘗試:
- 不確定想移除的套件「有多少依賴套件」
- 即使確定依賴套件,也無法確定這些套件「是否還被其他套件所依賴」
小結:pip 適用於小型專案,但缺乏相依性管理
對於小型專案或只需新增套件的專案,pip 尚可應付。但當專案規模擴大,需要移除套件以維持環境簡潔時,pip 缺少依賴解析的問題便會浮現。
尤其在容器化部署中,過多不必要的套件會增加 image 大小、浪費資源,並提高衝突風險。因此,若要乾淨移除過時套件且不影響其他套件,完整套件相依性管理工具是必要的。
從零開始使用 Poetry
好,前言到此結束,讓我們進入正題,開始上手學習 Poetry。
2023/04/08
:本文最初創作於 Poetry 版本 1.1.19 時期,部分指令已有變動,請以官方文件為準。
本文主要以 macOS 和 Linux(Ubuntu)環境來進行安裝及教學,Windows 用戶如果有無法順利安裝的情況,可參考官方文件內容修正。
安裝 Poetry
2023/12/30
:之前把安裝分為「全域」和「pip 安裝」兩種,具有一定誤導性。加上官方文件後來也更新了pipx
安裝方式,所以本段重新修訂。
Poetry 和 pip、git、pyenv 等工具一樣,都是典型的命令列工具,需要先安裝才能下達指令——poetry
。
安裝方式選擇
Poetry 是一個 Python 套件,需要有 Python 執行環境才能正常運行。
Poetry 提供了兩種主要的安裝方式:
- 使用
pipx
安裝。 - 使用 official installer(即下述的安裝指令)安裝。
以上兩種方式大同小異,核心內涵都是「自動為你建立一個 Python 虛擬環境,並在其中安裝 Poetry」,以達到 Poetry 安裝環境的獨立與隔離。
如果你平常沒在使用 pipx,那選擇第二種方式即可。
避免安裝 Poetry 至專案虛擬環境
安裝 Poetry 的時候,一定將它安裝在一個「專用」的虛擬環境。上述兩種安裝方式都滿足這個條件。
千萬不要為了方便,把 Poetry 直接安裝至你的專案虛擬環境,這麼做是危險的。
因為 Poetry 所依賴的套件非常多,總計超過 30 個,會嚴重影響專案虛擬環境的整潔度。這些依賴套件可能和專案本身的套件發生衝突。
所以官方文件才會提醒你:
Poetry should always be installed in a dedicated virtual environment to isolate it from the rest of your system. In no case, it should be installed in the environment of the project that is to be managed by Poetry.
使用 official installer 安裝 Poetry 至家目錄
我個人使用 official installer 安裝。
要用 official installer 安裝 Poetry,只要在命令列輸入下列指令。
macOS / Linux / WSL(Windows Subsystem for Linux)
1 | curl -sSL https://install.python-poetry.org | python3 - |
Windows
1 | (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python - |
Poetry 實際安裝路徑如下:
The installer installs the
poetry
tool to Poetry’sbin
directory. This location depends on your system:
$HOME/.local/bin
for Unix%APPDATA%\Python\Scripts
on Windows
以 macOS 為例,如果要下poetry
指令,就需要打完整路徑$HOME/.local/bin/poetry
,顯然不太方便,所以我們需要設定 PATH。
設定 PATH 環境變數
如果你選擇「official installer 安裝」,那這一步非常重要,我們必須先「手動設定」PATH,否則作業系統不知道poetry
指令的執行檔在哪,根本無法使用。
至於 PATH 是什麼,可以參考良葛格這篇〈PATH 是什麼?〉。
總之,我們要將poetry
執行檔所在的路徑(目錄)新增至 PATH。
在 macOS 或 Linux 上設定 PATH
使用 macOS 或 Linux,設定 PATH 的步驟相對簡單,只要在.zshrc
或.bashrc
或.bash_profile
新增:
1 | export PATH=$PATH:$HOME/.local/bin |
存檔後重啟 shell 即可使用。直接在命令列打上poetry
指令測試。
在 Windows 上設定 PATH
Windows 用戶可參考 JetBrains 的 Poetry 設定教學。我覺得寫得比 Poetry 官方文件更好懂:
1 | $Env:Path += ";C:\Users\jetbrains\AppData\Roaming\Python\Scripts"; setx PATH "$Env:Path" |
注意,上面的路徑要替換成你自己的使用者路徑——肯定不是jetbrains
:
Don’t forget to replace jetbrains with your username!
設定完後,重啟 shell,一樣,可直接在命令列打上poetry
指令測試。
設定 alias
比起pip
,poetry
這個指令實在太冗長了!我們還是給它一個 alias 吧!
基於它是我極為常用的指令,我願意賦與它「單字母」的 alias 特權,我使用p
:
1 | alias p='poetry' |
alias 是方便自己使用,但本文基於表達清晰考量,下面的解說除了圖片外,原則上並不會使用 alias 表示。
初始化 Poetry
為了方便解說,我們先建立一個全新的專案,名為poetry-demo
。
指令都很簡單,但還是建議可以一步一步跟著操作。
就像 git 專案需要初始化,Poetry 也需要,因為每一個使用了 Poetry 的專案中一定要有一個pyproject.toml
作為它的設定檔。否則直接使用poetry
相關指令就會出現下列錯誤訊息:
Poetry could not find a pyproject.toml file in {cwd} or its parents
所以一定先初始化,使用poetry init
:
1 | mkdir poetry-demo |
此時會跳出一連串的互動對話,協助你建立專案的資料,大部分可以直接enter
跳過:
1 | This command will guide you through creating your pyproject.toml config. |
直到出現「Would you like to define your main dependencies interactively? (yes/no) [yes]
」,我們先選擇「no」後,會讓你確認本次產生的toml
檔內容:
1 | Would you like to define your development dependencies interactively? (yes/no) [yes] no |
並詢問你「Do you confirm generation? (yes/no) [yes]
」,按enter
使用預設選項「yes」或直接回答「yes」,則pyproject.toml
建立完成。
此時專案目錄結構如下:
1 | poetry-demo |
管理 Poetry 虛擬環境
我覺得學習 Poetry 的第一道關卡,就是它對於虛擬環境的管理。
「強制」虛擬環境
Poetry 預設上(可透過poetry config
修改)會強制套件都要安裝在虛擬環境中,以免污染全域,所以它整合了virtualenv
。
所以在執行poetry add、install
等指令時,Poetry 都會自動檢查當下是否正在使用虛擬環境:
- 如果是,則會直接安裝套件至當前的虛擬環境。
- 如果否,則會自動幫你建立一個新的虛擬環境,再進行套件安裝。
容易混淆的虛擬環境
Poetry 主動納入虛擬環境管理算是立意良善,相當於把pip
+venv
兩者的功能直接整合在一起,但也帶來一定的複雜度,尤其在你已經自行使用了venv
、virtualenv
或 pyenv-virtualenv
或conda
等工具來管理虛擬環境的情況下!
沒錯,Python 的虛擬環境管理就是這麼麻煩!
個人建議,對新手而言,於 Poetry 的專案中,一律透過 Poetry 來管理虛擬環境即可。我目前也是這樣,省得麻煩。
以指令建立虛擬環境
使用指令poetry env use python
:
1 | ❯ poetry env use python |
可以看出 Poetry 為我們建立了名為poetry-demo-IEWSZKSE-py3.8
的虛擬環境。
重點說明
poetry env use python
建立虛擬環境所使用的 Python 版本,取決於python
指令在你的「PATH」是連結到哪個版本。- 你也可以將指令最後的
python
,改為python3
或python3.8
,甚至只需要3.8
,只要它們確實存在於 PATH 中。 - 更多資訊可參考官方文件。
- 你也可以將指令最後的
- 預設上,Poetry 會統一將虛擬環境建立在「特定目錄」裡,比如本例中存放的路徑是
/Users/kyo/Library/Caches/pypoetry/virtualenvs
。 - 虛擬環境的命名模式為
專案名稱-亂數-Python版本
。
最後一點,老實說我個人不是很喜歡這樣的做法,因為這意味著單一專案允許建立複數個虛擬環境(比如 Python 3.7、3.8、3.9 可以各來一個),彈性之餘也增加了混亂的可能,而且這命名模式我也不太欣賞,顯得有點冗長。
既然 Python 的虛擬環境理論上都是高度綁定專案本身的,我更偏好venv
式的做法,也就是把虛擬環境放到專案目錄內,而非統一放在獨立的目錄,讓虛擬環境與專案呈現直觀的一對一關係。
所幸,Poetry 具備這樣的選項。
修改config
,建立專案內.venv
虛擬環境
我們先使用poetry config
指令來查看 Poetry 目前幾個主要的設定,需要--list
這個參數:
1 | ❯ poetry config --list |
其中virtualenvs.create = true
若改成false
,則可以停止 Poetry 在「偵測不到虛擬環境時會自行建立」的行為模式,但建議還是不要更動。
而virtualenvs.in-project = false
就是我們要修改的目標,使用指令:
1 | poetry config virtualenvs.in-project true |
我們先把之前建立的虛擬環境刪除:
1 | ❯ poetry env remove python |
重新建立,看看行為有何差異:
1 | ❯ poetry env use python |
可以看出:
- 虛擬環境的路徑改為「專案的根目錄」。
- 名稱固定為
.venv
。
這樣的設定更加簡潔。
啟動與退出虛擬環境
啟動虛擬環境,需移至專案目錄底下,使用指令poetry shell
:
1 | ❯ poetry shell |
poetry shell
指令會偵測當前目錄或所屬上層目錄是否存在pyproject.toml
來確定所要啟動的虛擬環境,所以如果不移至專案目錄,則會出現下列錯誤:
1 | ❯ poetry shell |
退出就簡單多了,只需要exit
即可。
Poetry 指令
Poetry 是一個獨立的命令列工具,就像 pyenv,它有自己的指令,需要花費額外的心力學習,且較 pip 更加複雜,這可能是使用 Poetry 的第二道關卡。好在常用的指令,其實也不超過 10 個,下面就來一一介紹。
在此我們繼續使用前面提過的 Flask 和 Black 套件,來示範並說明 Poetry 的優勢以及它和 pip 的不同之處。
Poetry 新增套件
使用指令:
1 | poetry add |
相當於pip install
,我們來試著安裝 Flask 看看會有什麼變化:
圖中可以看出 Poetry 漂亮的命令列資訊呈現,會清楚告知總共新增了幾個套件。
此時專案中的pyproject.toml
也會發生變化:
1 | ... |
這裡要說明,安裝 Flask,則pyproject.toml
就只會新增記載Flask = "^2.1.1"
這個 top-level 的 package 項目,其餘的依賴套件不會直接記錄在toml
檔中。
我覺得這是一大優點,方便區分哪些是你主動安裝的主要套件,而哪些又是基於套件的依賴關係而一併安裝的依賴套件。
poetry.lock
與更新順序
除了更新pyproject.toml
,此時專案中還會新增一個檔案,名為poetry.lock
,它實際上就相當於 pip 的requirements.txt
,詳細記載了所有安裝的套件與版本。
當你使用poetry add
指令時,Poetry 會自動依序幫你做完這三件事:
- 更新
pyproject.toml
。 - 依照
pyproject.toml
的內容,更新poetry.lock
。 - 依照
poetry.lock
的內容,更新虛擬環境。
由此可見,poetry.lock
的內容是取決於pyproject.toml
,但兩者並不會自己連動,一定要基於特定指令才會進行同步與更新,poetry add
就是一個典型案例。
此時專案目錄結構如下:
1 | poetry-demo |
poetry lock
:更新 poetry.lock
當你自行修改了pyproject.toml
內容,比如變更特定套件的版本(這是有可能的,尤其在手動處理版本衝突的時候),此時poetry.lock
的內容與pyproject.toml
出現了「脫鉤」,必須讓它依照新的pyproject.toml
內容更新、同步,使用指令:
1 | poetry lock |
如此一來,才能確保手動修改的內容,也更新到poetry.lock
中,畢竟虛擬環境如果要重新建立,是基於poetry.lock
的內容來安裝套件,而非pyproject.toml
。
還是那句話:
poetry.lock
相當於 Poetry 的requirements.txt
。
但要特別注意的是,poetry lock
指令,僅會更新poetry.lock
,「不會」同時安裝套件至虛擬環境:
This command locks (without installing) the dependencies specified in pyproject.toml.
因此,在執行完poetry lock
指令後,你必須再使用poetry install
來安裝套件。否則就會出現poetry.lock
和虛擬環境不一致的狀況。
更多poetry lock
細節可參考官方文件,其中特別值得注意的是--no-update
參數。
指定套件「版本」範圍
2024/01/05
新增。
回想我們使用 pip 的時候,requirements.txt
的內容通常是長這樣:
1 | blinker==1.6.3 |
所有套件的版本都是固定的!
如前所述,那是因為 pip 並不擅長管理套件的版本衝突,所以固定是最保險的。但代價是,專案無法輕易更新套件版本,容易過時,造成後續開發與維護的麻煩。
你可以試著手動修改requirements.txt
,但隨之而來的是一陣陣手動處理版本衝突的痛苦😱
Poetry 的版本管理能力
使用 Poetry,情況將大不相同,因為 Poetry 能夠管理套件的版本衝突,所以我們可以放心地透過「範圍」來指定套件的版本。
這樣的好處是,在不影響專案穩定性(不發生套件版本衝突)的前提下,自動更新套件至範圍內的最新版,且不需要手動修改pyproject.toml
。
當然,如果你認為這不夠保險,還是可以在安裝時,指定套件的「特定」版本。或後續手動修改pyproject.toml
,讓套件版本固定。
Poetry 的add
指令,可以用下列方式指定套件版本(前二者須搭配@
運算子),我們以安裝 Django 4.2 LTS 為例。
一、使用^
符號(文件)
指定 Django 版本為 >=4.2.9 且 <5.0.0(允許 4.2.9 及以上版本,但不包括 5.0.0,即最大版號不能變更):
1 | poetry add django@^4.2.9 |
這意味著它會接受所有 4.x.x 的更新,只要版本號小於 5.0.0。這是一個常見的做法,因為它允許套件自動更新到任何非重大變更的新版本。
二、使用~
符號(文件)
指定 Django 版本為 >=4.2.9 且 <4.3.0(允許 4.2.9 及以上版本,但不包括 4.3.0,即只能升級最小版號):
1 | poetry add django@~4.2.9 |
這個選項更加保守,只會接受 4.2.x 系列的更新。這適合想要進一步限制更新的範圍,但又保留一些更新的彈性——僅包括 bug 修正和小幅度的改進。
三、使用>=
符號
指定 Django 版本為 >=4.2.9(沒有上限):
1 | # 注意,這裡需要使用「字串」表示 |
主版號(即上面的 4.x.x 中的 4)升級時,通常有更大機率引入 API 變更、棄用舊有的 API 等,也就是所謂的 breaking change。
這樣的更新可能會導致你的專案無法正常運作,需要一併修改程式碼。所以一般不建議使用這種方式。
四、固定版本
僅允許 Django 的 4.2.9 版本(嚴格限制在這個版本):
1 | poetry add django==4.2.9 |
安全、保險,但也浪費了 Poetry 的版本管理能力。
一般我只在 linter、formatter 等工具上使用固定版本,自己手動更新。因為它們必須和 pre-commit 設定檔中的版本一致。所以我不會讓它們自動升級。
依我個人經驗,最常用的是第 1 和第 4 種方式。
新增套件至 dev-dependencies
有些套件,比如pytest
、flake8
等等,只會在開發環境中使用,產品的部署環境並不需要。
Poetry 允許你區分這兩者,將上述的套件安裝至dev-dependencies
區塊,方便讓你輕鬆建立一份「不包含」dev-dependencies
開發套件的安裝清單。
在此以 Black 為例,安裝指令如下,舊版:
2025/05/15
:在 Poetry 2.0.0 以後,--dev
參數又復活了!
Remove deprecated CLI options and methods and revoke the deprecation of
--dev
(#9732).
1 | poetry add black --dev |
新版,Poetry >= 1.2.0:
1 | poetry add black --group dev |
結果的區別顯示在pyproject.toml
裡:
1 | ... |
可以看到black
被列在不同區塊:tool.poetry.dev-dependencies
。
強烈建議善用 dev-dependencies
善用-D
參數,明確區分開發環境專用的套件,我認為非常必要。
首先,這些套件常常屬於「檢測型」工具,相關的依賴套件著實不少!比如flake8
,它依賴了pycodestyle
、pyflakes
、mccabe
等等,還有black
、pre-commit
,依賴套件數量也都很可觀。
其次,既然它們都只在開發階段才需要,則完全可以從部署環境中缺席。如果不分青紅皂白一律安裝到dependencies
區塊,部署環境容易顯得過於臃腫。
常見的dev-dependencies
區塊項目,例示如下:
1 | [tool.poetry.dev-dependencies] |
Poetry 更新套件
這個就很簡單了,使用poetry update
指令即可:
1 | poetry update |
上面指令會更新全部「可能可以更新」的套件,你也可以僅指定特定套件,比如:
1 | poetry update requests toml |
關於poetry update
的其餘參數,請參考文件。
還一件重要的事,那就是關於套件版本的升級限制規則,取決於你在pyproject.toml
中的設定。
這部分稍嫌複雜,且有多種表達方式,可見 Dependency specification。
列出全部套件清單
類似pip list
,這裡要使用poetry show
:
1 | ❯ poetry show |
特別提醒的是,這裡的清單內容並不是來自於虛擬環境,這點和 pip 不同,而是來自於poetry.lock
的內容。
「樹狀」顯示套件依賴層級
Poetry 最為人津津樂道的就是它的樹狀顯示——poetry show --tree
。
1 | ❯ poetry show --tree |
讓主要套件與其依賴套件的關係與層次,一目了然。
你也可以只顯示「特定套件」的依賴層級,以celery
為例:
1 | ❯ poetry show celery --tree |
Poetry 移除套件
使用poetry remove
指令。和poetry add
一樣,可以加上-D
參數來移除置於開發區的套件。
而移除套件時的「依賴解析(相依性管理)」能力,正是 Poetry 遠優於 pip 的主要環節,因為 pip 沒有嘛!也是我提議改用 Poetry 的關鍵理由——為了順利移除套件。
前面已經提過,pip 的pip uninstall
只會移除你所指定的套件,而不會連同依賴套件一起移除。
前面也舉了 Flask 和 Black 都共同依賴click
這個套件的例子,在手動移除套件的情況下,你可能未曾注意 Black 也依賴了click
,結果為了「徹底移除」Flask 的所有相關套件,不小心把click
也移除掉了。
所以,使用 pip 時,我們鮮少會去移除已經不再使用的套件。畢竟依賴關係錯綜複雜,移除套件可能造成許多「副作用」,實在是太麻煩了。
poetry remove
的依賴解析能力
而 Poetry 會幫你處理這些棘手的「套件相依性」難題,讓你輕鬆移除 Flask 而不影響 Black:
poetry remove flask
可以對比上面安裝 Flask 時的截圖,那時總共安裝了 8 個套件,但現在移除的卻只有 7 個——沒錯,因為有依賴解析,Poetry 知道 Black 還需要click
!所以不能移除:
1 | ❯ poetry show --tree |
一個套件直到環境中的其餘套件都不再依賴它,Poetry 才會安心讓它被移除。
輸出 requirements.txt
理論上,全面改用 Poetry 後,專案中是不需要存在requirements.txt
,因為它的角色已經完全被poetry.lock
所取代。
但事實是,你可能還是需要它,甚至希望它隨著poetry.lock
的內容更新!至少對我而言就是如此,我在 Docker 部署環境中並不使用 Poetry,所以我需要一份完全等價於poetry.lock
的requirements.txt
,用於 Docker 部署。
此時需要使用poetry export
指令,這個指令會根據poetry.lock
的內容,輸出一份requirements.txt
檔案。
預設的輸出結果會有 hash 值,不想納入 hash 則要加上參數去除。以下就是我固定用來輸出requirements.txt
的指令與參數:
1 | poetry export -f requirements.txt -o requirements.txt --without-hashes |
Poetry 常用指令清單
算來算去,Poetry 的常用指令主要有下面幾個:
poetry add
poetry remove
poetry export
poetry env use
poetry shell
poetry show
poetry init
poetry install
其中一半,單一專案可能只會用個一兩次而已,比如init
、install
和env use
,實際上需要學習的指令並不多。
那麼,只要知曉這些指令,就可以順利運用 Poetry 了嗎?可能是,也可能否,所以我下面還會再補充 Poetry 的常見使用情境與操作方式,讓你接納 Poetry 的阻力可以進一步下降!
Poetry 常見使用情境與操作 QA
這部分會以「使用場景」的角度切入,介紹 Poetry 應用情境與操作說明,還包括一些自問自答:
一、新增專案並使用 Poetry
這是最理想的狀態,沒有過去的「包袱」,可謂是最能輕鬆採用 Poetry 的情境。
使用順序不外乎是:
poetry init
:初始化,建立pyproject.toml
。poetry env use python
:建立專案虛擬環境並使用。poetry shell
:進入專案但虛擬環境還未啟動,以這個指令啟動。如果使用本指令時虛擬環境尚未建立或已移除,則會直接自動幫你建立虛擬環境並使用。poetry add
:安裝套件並寫入虛擬環境。必要時使用-D
參數,使其安裝至 dev 區塊。poetry remove
:移除套件,若是移除 dev 區塊的套件,需要加上-D
參數。
這部分和前面內容沒有差別,因為前面內容就是以全新專案作為基礎。
二、現有專案改用 Poetry
極為常見的需求,但並沒有很正式的做法,因為不存在poetry import
之類的指令。
常見的做法是使用 shell 指令將requirements.txt
的內容匯入:
1 | cat requirements.txt | xargs poetry add |
然而這樣做是有可能遇到一些問題的,因為 Poetry 對套件的版本衝突比較敏感,所以即便用pip install -r requirements.txt
都能正常安裝,透過上述指令的遷移過程卻仍有機會出現錯誤。
只能說這個「手動 import」做法實在是不得已,我覺得最好的做法還是一一在 Poetry 中重新安裝,長痛不如短痛,這樣能確保不會有任何問題。
三、在別台主機上重現專案的 Poetry 虛擬環境
這也是非常常見的需求。
第一步當然是git clone
專案,此時專案中已經有 Poetry 所需的必要資訊了——也就是pyproject.toml
和poetry.lock
。
你還缺少的僅僅是虛擬環境。如果是全新的主機,則還得先安裝、設定好 Poetry。
確定 Poetry 可正常使用後,移至專案目錄底下,依序執行指令:
poetry env use python
:建立專案虛擬環境並使用。poetry install
:因為是舊專案,不需要init
,會直接依poetry.lock
記載的套件版本安裝到虛擬環境中!類似npm install
。
四、我想要移除並重建虛擬環境
在使用「專案內虛擬環境」方案,也就是.venv
的前提下,想要刪除這個虛擬環境並加以重建,不能使用poetry env remove python
指令,很可能會出錯。
不過有更簡單的做法——直接刪除.venv
資料夾即可。
然後再poetry env use python
或poetry shell
建一個新的就好。
五、為什麼我不在 Docker 環境中使用 Poetry?(已更新)
因為啟動容器後需要先安裝 Poetry 到全域,或打包一個帶有 Poetry 的 image,兩者都會增加新的耦合與依賴,需要更細緻的管理。
但可以使用 multi-stage build 來解決這個問題,具體可參考系列第三篇——〈Docker 教學:用 Multi-stage build 建立 Poetry 虛擬環境〉。
結語:井然有序的複雜
總的來說,Poetry 是一款優秀的套件管理工具,但並不像 pip 那般簡單、好上手。
使用 Poetry 來管理專案的套件與虛擬環境,需要一定的學習成本,但帶來的效益還是相當可觀的,尤其在你希望能夠乾淨且安心地移除套件之際,可謂莫它莫屬。
所以,別再猶豫,從今天起,加入 Poetry 的行列吧!
參考
- https://python-poetry.org/docs/
- https://github.com/python-poetry/poetry
- https://github.com/python-poetry/poetry/issues/3248
- https://github.com/python-poetry/poetry/issues/5185
- Python - 取代 Pipenv 的新套件管理器 Poetry
- 相比 Pipenv,Poetry 是一個更好的選擇
- pip, pipenv 和 poetry 的選擇
- Dependency Management With Python Poetry
- Ep 15. 和 PyPA 的成員聊聊 Python 開發工作流
- Python - Poetry