使用 Poetry 管理 Python 套件
Poetry vs pip
Poetry 與 pip 一樣可以用於套件管理,但多了以下功能:
- 虛擬環境管理:使用內建的 venv 或 virtualenv 套件來建立及管理 Python 的虛擬環境,不同虛擬環境間彼此獨立
- 套件相依性管理:管理環境中所安裝的全部套件及其版本。若一個套件被兩個以上的套件依賴 (dependency),而彼此要求的版本範圍沒有交集,則套件可能會失效或無法安裝。
- 套件的打包與發布
pip 的缺點:
- 沒有完整套件相依性管理功能,難以乾淨地移除套件。
- 若一個套件有多個依賴套件,在使用
pip uninstall
時無法找出這些依賴套件並移除。若強行移除依賴套件可能會導致另一個依賴它的套件失效。
安裝 Poetry
Poetry 主要有兩種安裝方式,官方推薦使用全域安裝。
-
Linux, macOS, Windows (WSL)
curl -sSL https://install.python-poetry.org | python3 -
-
Windows (Powershell)
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
Poetry 安裝路徑
- Unix 系統:
$HOME/.local/bin
- Windows 系統:
%APPDATA%\Python\Scripts
將此路徑加入環境變數即可在終端機直接使用 poetry
指令。
初始化 Poetry 專案設定
每一個使用 Poetry 的專案都需要一個 pyproject.toml
設定檔,因此進入新的專案要先初始化。
首先進入專案資料夾並輸入 poetry init
:
cd <project folder>
poetry init
接著會進入互動式的介面,前五項可以直接 enter 確認,第六項 Compatible Python versions
請確認是否符合你要的 Python 版本,若要更改請輸入 ^3.x
。
最後兩項先輸入 no 跳過,接著會讓你確認即將產生的內容,最後再按 enter 確認即可:
This command will guide you through creating your pyproject.toml config.
Package name [reminder-bot]:
Version [0.1.0]:
Description []:
Author [Your Name <you@example.com>, n to skip]:
License []:
Compatible Python versions [^3.9]:
Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Generated file
[tool.poetry]
name = "reminder-bot"
version = "0.1.0"
description = ""
authors = ["JHTNT <jerry1106666@gmail.com>"]
readme = "README.md"
packages = [{include = "reminder_bot"}]
[tool.poetry.dependencies]
python = "^3.9"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
可以看到目錄裡多了 pyproject.toml
就表示初始化完成了。
管理 Poetry 虛擬環境
Poetry 整合了 virtualenv
,預設強制將套件安裝在虛擬環境,若輸入指令時不在虛擬環境中會自動建立一個新的虛擬環境。
但是 Poetry 預設將虛擬環境放在同一個資料夾集中管理,個人更偏好 venv
建立在專案目錄內的方式,因此需要修改 Poetry 的設定。
修改 Poetry config
輸入 poetry config --list
來查看有哪些指令,我們要修改的是 virtualenvs.in-project = null
這一項
使用以下指令來修改設定:
poetry config virtualenvs.in-project true
若之前建立過虛擬環境先刪除:
poetry env remove python
接著建立新的虛擬環境(若電腦只有一個 Python 版本):
poetry env use python
建立新的虛擬環境(使用 pyenv 管理)
poetry env use $(pyenv which python)
關於使用 pyenv 管理 Python 版本可以參考使用 pyenv 管理 Python 版本。
啟動與退出虛擬環境
輸入 poetry shell
啟動虛擬環境,再輸入 exit
可以退出。
Poetry 指令
新增套件
相當於 pip install
,會詳細列出安裝了哪些套件。
poetry add <package name>
可以發現 pyproject.toml
的 tool.poetry.dependencies
區域多了剛剛新增的套件及版本,且只有我們主動新增的套件。
新增開發環境套件
在開發專案時可能會用到一些測試或檢查的工具,但在部署時是不需要的,此時可以加上 ,將工具與必要的套件區分。--dev
或 -D
參數
poetry add <package name> --group dev
poetry add <package name> -G dev
目前 poetry 已棄用 --dev
, -D
的參數,改為使用 --group dev
/ -G dev
。
這樣新增的套件會出現在 tool.poetry.dev-dependencies
區域。
poetry.lock
的更新
執行上述的 poetry add
以及稍後會介紹的 poetry remove
時可以發現,除了 pyproject.toml
以外還有另一個叫 poetry.lock
的檔案內容會變動。這個檔案相當於 pip 的 requirements.txt
,記錄了所有安裝的套件與版本。
當你執行 poetry add
時,Poetry 實際上做了三件事:
- 更新
pyproject.toml
- 解析
pyproject.toml
的套件版本後,更新poetry.lock
- 根據
poetry.lock
的內容更新專案的套件
由於 pyproject.toml
與 poetry.lock
不會自動同步,若手動編輯 pyproject.toml
後需要更新 poetry.lock
的內容,可以使用 poetry lock
指令,但直接執行的話會「順便」將依賴套件更新到最新版,這可能會導致某些問題,因此可以加上 --no-update
參數來避免此行為:
poetry lock --no-update
更新完 poetry.lock
之後還不會更新套件,需要再執行此指令:
poetry install
更新套件
指令很直覺,就是 update
,這樣會一次更新專案中所有可更新的套件:
poetry update
若只想要更新特定幾個套件,可以在後面指定套件名稱:
poetry update <package 1> [<package 2> ...]
需要注意的是可以更新的版本會受到 pyproject.toml
的限制,例如 black = "^23.3.0"
。比較常用的是語意化版本的方式,可以查看語意化版本 (Semantic Versioning) 是什麼(未寫),其他詳細的方法參考 Poetry 的官方文件 Dependency specification。
列出套件清單
指令為 poetry show
,等同於 pip list
。注意套件清單的來源是 poetry.lock
而不是虛擬環境。
poetry show
若要使用樹狀顯示可以加上 --tree
參數,可以很直觀的看出主要套件與其依賴套件的關係:
poetry show --tree
還可以只顯示指定套件的依賴清單:
poetry show <package name> --tree
移除套件
使用方法就跟 poetry add
一樣,加上 --dev
或 -D
可以移除開發用的套件。
這也是與 pip 最大的不同,Poetry 具有相依性管理的能力,可以確認要移除的套件有哪些依賴套件,並確保這些依賴套件不被其他套件使用才移除。
輸出 requirements.txt
有時候在某些環境還是會有使用 requirements.txt
的需求,此時可以用 poetry export
來導出套件,雖然看起來跟平常熟知的 requirements.txt
不一樣,但還是能正常使用。
poetry export -o requirements.txt
Reference
- 再見了 pip!最佳 Python 套件管理器——Poetry 完全入門指南 - Code and Me
- Introduction | Documentation | Poetry - Python dependency management and packaging made easy
- Dependency Management With Python Poetry – Real Python
- PyEnv + Poetry: Poetry does not use correct Python versions · Issue #5252 · python-poetry/poetry
- breaking change: invert
lock --no-update
tolock --update
(or similar) · Issue #3248 · python-poetry/poetry