如何使用 uv 取代 pip 來改善 Python 專案的開發流程

  1. 關於 uv
  2. 基本安裝與設定
    1. 安裝 uv
    2. 設定 auto complete
  3. 專案初始化
  4. 建立 Python 虛擬環境
  5. 使用 uv 管理 Python 套件與版本
    1. 安裝 Python 套件
    2. 移除 Python 套件
    3. 顯示套件相依性
  6. 執行 Python 程式碼
  7. Tool 功能(例如:程式碼檢查)
  8. 總結
  9. 參考資料

關於 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

初始化後的檔案夾結構

  • .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 取代 pip 來改善 Python 專案的開發流程〉中有 1 則留言

回覆給如何使用 Python 套件管理工具「uv」取代 pip 來加速 Docker Image 的建立 – JumpingCode 資料科學手記 取消回覆