關於 uv
uv 是一個以 Rust 撰寫的 Python 套件管理工具,安裝套件的速度比 pip 還要快 10-100 倍,有部分開源專案的官網文件的安裝步驟也已經預設使用 uv 取代 pip(如下圖的 Prefect),如果是想要在 Docker 中採用 uv 的話可以參考一下我之前寫的 uv + Docker 的教學 文章 。

近期因為 uv 持續推出很多好用的功能,到現在我所有的專案都已經替換成 uv 來開發,不再使用原本的 pip 了,所以這次想要來整理並分享我自己在開發 Python 專案時使用 uv 的流程。
基本安裝與設定
安裝 uv
# For MacOS
brew install uv
# For Windows
powershell -ExecutionPolicy ByPass -c "irm <https://astral.sh/uv/install.ps1> | iex"

其他詳細安裝方式可參考:https://docs.astral.sh/uv/getting-started/installation/#installing-uv
設定 auto complete
接著我們可以先設定好「自動補完指令」,如果你跟我一樣 Terminal 是使用 zsh 的話,可以用下方的指令來設定
# 設定 auto complete
echo 'eval "$(uv generate-shell-completion zsh)"' >> ~/.zshrc
完成後我們可以試著輸入 uv python 後按下 tab 鍵就會出現建議的指令,方便我們直接選擇或是參考

詳細說明可參考官網:https://docs.astral.sh/uv/getting-started/installation/#shell-autocompletion
(備註:如果還不知道怎麼美化你的 Mac Terminal 的話,可以參考我之前的完整教學 ⬇️)
專案初始化
首先我們要初始化我們的專案,只要在專案路徑下執行 uv init,或是你也可以在該路徑底下再另外建一個指定名稱的資料夾,如下方的指令就是在資料夾內建立一個 my_first_project 的專案
# 初始化專案
uv init my_first_project

初始化後的檔案夾結構
my_first_project
├── .git
├── .gitignore
├── .python-version
├── main.py
├── pyproject.toml
└── README.md
- .git, .gitignore: Git 所需的基本檔案
- .python-version: 會依照你本機系統的 Python 版本,例如我的本機是 Python 3.13,這個檔案裡面就會單純寫著 「3.13」 這幾個字
- main.py: 預設的主程式,只有 print 一行專案名稱的功能
- pyproject.toml: 最重要的專案檔案,記載所有套件版本與相關工具的地方
- README.md: 專案說明文件,預設是空白
建立 Python 虛擬環境
接著我們可以來建立 Python 虛擬環境,這邊只要使用 uv venv 指令並指定 Python 版本就搞定了!
如果我本機安裝的原本是 3.13 版本,但我想要在這個專案中使用 3.12,那就輸入下方的指令,uv 就會幫我們建立一個 .venv 資料夾(跟以前使用 python virtualenv 套件一樣),如果突然想要切換 venv 的版本,只要把最後面的版本數字改成指定版本,再次執行指令即可。
# 建立一個 Python 3.12 虛擬環境
uv venv --python 3.12

# 再次執行,但是將虛擬環境改成 Python 3.11
uv venv --python 3.11
預設的虛擬環境名稱就會是 .venv,當然我們也可以指定這個虛擬環境的名稱,例如 my_venv
# 指定虛擬環境的名稱
uv venv my_venv --python 3.12

安裝完可以將 .python-version 改成專案的 Python 版本
# 更新 .python-version 內容
uv python pin 3.12

補充:若建立虛擬環境時出現類似我上方的 Warning 的話,只要把 pyproject.toml 中的 requires-python 改成專案可以容許的版本(例如下方的 >= 3.9,原本是 >= 3.13 所以會出警告),就可以消除原本建立時的 Warning 了
# 解決建立虛擬環境時遇到 Warning 的問題
[project]
name = "my-first-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.9"
dependencies = []

可以透過以下指令檢查目前本機所有的 Python 版本與路徑
# 檢查所有的 Python 版本與路徑
uv python list

使用 uv 管理 Python 套件與版本
安裝 Python 套件
在安裝前的 pyproject.toml 檔案的 dependencies 是空的
# 尚未安裝任何套件時
[project]
name = "my-first-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.9"
dependencies = []
假設我們今天想要安裝 pandas 和 fastapi,只要輸入以下指令,uv 就能高速完成套件安裝(是真的超快!)
# 安裝指定套件
uv add pandas fastapi

接著我們可以再觀察一次 pyproject.toml 的內容,會發現他出現了剛剛安裝的套件,並且附上安裝的版本,因為我前面沒有指定,所以這邊就是安裝了套件最新的穩定版本
# 使用 uv add 安裝套件後
[project]
name = "my-first-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.9"
dependencies = [
"fastapi>=0.115.12",
"pandas>=2.2.3",
]
同樣的指令也可以用來「指定/升級/降級」版本,例如原本的 pandas 是 2.2.3,我用 uv add 指令指定安裝 2.2.1,就會發現 uv 幫我們刪除 2.2.3 同時安裝好 2.2.1 版本的 pandas

移除 Python 套件
若今天我發現我專案不需要 pandas 了,就可以使用 uv remove 指令移除指定套件,且會移除相依套件
# 移除指定套件
uv remove pandas

執行後 pyproject.toml 也會同步更新,pandas 已經不在 dependencies 內
# 移除套件後 dependencies 有變更
[project]
name = "my-first-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.9"
dependencies = [
"fastapi>=0.115.12",
]
這邊順便提一下,我覺得採用 pyproject.toml 的方式很棒,以前使用 requirements.txt 的時候,會用 pip freeze 的指令來將當下的套件清單與版本寫入到檔案中,而且會包含所有相依的套件,導致清單很長,原本的 pip uninstall 也只會移除指定的套件,不會移除相依套件,會讓 requirements.txt 檔案累積不少技術債,pyproject.toml 則很簡單的顯示了我實際安裝的主要套件,不會顯示相依套件,而且在移除時也會直接將相依套件一併刪除,方便很多。
顯示套件相依性
有另一個好用的指令是 uv tree 可以讓我們一目瞭然現在這個專案中的套件相依性,這個功能在解決版本衝突的時候很方便。
# 查看套件相依性
uv tree

也可以指定要顯示的層數(-d, –depth: 深度)
# 指定套件相依性的顯示深度
uv tree -d 2

執行 Python 程式碼
若我們想要透過指令的方式來執行 main.py 檔,就可以使用 uv run 指令,uv 就會自動使用這個專案的虛擬環境去執行 main.py
# 這是一個隨便寫的 main.py
import pandas as pd
print("Hello, World!")
# 用 uv 來執行 python 檔
uv run main.py

Tool 功能(例如:程式碼檢查)
有一個實用的指令是 uv tool 讓我們可以使用像是 ruff 這種程式碼檢查工具
# 用 ruff 執行程式碼檢查(原版)
uv tool run ruff check
由於這段指令比較長,所以 uv 提供了一個更方便的指令 uvx 來取代 uv tool run,兩者是一樣的功能
# 用 ruff 執行程式碼檢查(精簡版)(推薦)
uvx ruff check
實際執行的結果如下圖,我的 main.py 中只有 import pandas 但是沒有使用到任何 pandas,ruff 就會發現這不符合 Ruff 所制定的 F401 的 Coding 規範,也可以在 uvx ruff check 後加上 –fix 來讓 Ruff 可以幫我門直接修正錯誤(在這邊的範例就是會刪除 import pandas 那一行程式碼)。

如果是想要直接安裝 ruff 的話,也可以使用 uv 安裝,這樣就可以直接使用 ruff check,不用輸入 uvx 了
# 安裝 ruff 工具
uv tool install ruff
# 有安裝 ruff 就可以直接執行
ruff check
# 免安裝版:使用 uvx 指令
uvx ruff check
其他詳細說明可參考官網:https://docs.astral.sh/uv/concepts/tools/#the-uv-tool-interface
總結
以上就是我個人目前在開發 Python 專案時會跑的基本流程,目前用起來都還算滿意,也很鼓勵大家可以嘗試轉換到 uv 試試看,我身邊同事用過也都說回不去了 😂
我這邊也整理了這篇文章所使用到的指令流程圖,方便大家做參考與實作!

uv 其實還有非常多功能我還沒有用到,之後有空再來分享該怎麼透過像是 uv sync 的方式來協作!
[…] (若是想了解 uv 在 Python 專案上的開發流程:如何使用 uv 取代 pip 來改善 Python 專案的開發流程) […]
讚讚