前言

作為 Python 開發者,你大概都踩過同一批坑:requirements.txt 在本機跑得好好的,換一台機器就版本衝突;conda 解析依賴跑了二十分鐘;新人入職第一天光搭環境就花掉半天。

這篇文章比較 venv、conda 和 uv 三種工具,重點放在實際使用差異,以及 uv 為什麼不只是「更快的 pip」——它其實已經是一套完整的專案管理工具鏈。

venv:Python 內建的解決方案

venv 從 Python 3.3 起內建,不需要額外安裝是它最大的優點。

1
2
3
4
python -m venv myenv
source myenv/bin/activate # Linux / macOS
myenv\Scripts\activate # Windows
pip install -r requirements.txt

適合的場景:

  • 快速開一個臨時環境驗證想法
  • CI 環境裡只需要標準工具鏈
  • 維護老專案,不想引入額外依賴

限制:

  • pip 的依賴解析速度慢,套件數量一多就有感
  • 不管理 Python 版本本身,需要另外用 pyenv 或系統 Python
  • 多個環境之間沒有統一的管理介面,只能靠自己記住路徑

在一個中型專案中,requirements.txt 達到 50 幾個套件時,每次在新機器上 pip install 要等 5 到 10 分鐘——對頻繁開環境的工作流來說,這個等待是真實的摩擦。

conda:資料科學生態的選擇

conda 是 Anaconda 發布的套件管理與環境管理系統,在資料科學領域有豐富的積累。

1
2
3
conda create -n myenv python=3.10
conda activate myenv
conda install numpy pandas scikit-learn

conda 的核心優勢:

  • 管理的不只是 Python 套件,還包含 C/C++ 預編譯 binary(例如 Intel MKL、libstdc++)。這對 numpy、scipy 這類底層依賴 C 函式庫的套件特別有用——conda 直接給你編好的 binary,不需要本機有編譯工具鏈
  • conda-forge 頻道提供大量科學計算套件,且版本相容性經過測試
  • 環境匯出與還原(conda env export / create)工作流程成熟

實際使用的問題:

  • Anaconda 完整安裝佔幾個 GB;miniforge 輕量一些但設定步驟多
  • 環境啟動速度比 venv 慢,在 shell 啟動時會有感
  • 依賴解析在複雜環境下可能跑很久,甚至解析失敗回報「無法滿足」但 pip 裝得起來
  • 在某些企業網路環境,defaults 頻道受限,需要切換到 conda-forge 或設 proxy

uv:不只是更快的 pip

uv 是什麼

uv 是由 Astral 開發、以 Rust 撰寫的 Python 套件與專案管理工具,2024 年 2 月釋出第一版。Astral 的核心成員包括 Ruff linter 的原作者 Charlie Marsh,以及 ripgrep、bat、hyperfine 等工具的作者。

安裝方式:

1
2
3
4
5
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

uv 的兩個使用模式

很多人看到 uv 只想到「pip 加速器」,但這只用到了表面功能。uv 實際上提供兩套工作流:

模式一:pip 相容介面(現有專案的直接替換)

1
2
3
uv venv myenv
source myenv/bin/activate
uv pip install -r requirements.txt

指令結構和 pip 幾乎一樣,速度大幅提升。這是最低阻力的切入點。

注意「幾乎」:uv 不是 100% 相容 pip。主要差異包括:多個 index 來源時 uv 遇到第一個包含目標套件的 index 就停止(pip 會合併所有 index 的版本再選最佳);預設不允許安裝到沒有虛擬環境的全域環境;pre-release 版本需要明確 opt-in。多數情況沒問題,但如果你的環境有複雜的 --extra-index-url 設定,切換前值得測試一下。

模式二:uv 專案管理工作流(新專案推薦)

1
2
3
4
5
uv init my-project
cd my-project
uv add requests pandas
uv run python main.py
uv sync # 根據 uv.lock 同步環境

uv init 會建立 pyproject.toml.python-version.venvuv.lock。之後 uv add 直接更新 pyproject.toml 並重新鎖定依賴,uv sync 讓環境和鎖定檔保持一致。這個工作流和 Poetry/PDM 類似,但速度快很多,且不需要另外安裝工具。

Python 版本管理

uv 內建 Python 版本管理,這是它相對 venv 最大的差異化功能之一:

1
2
3
4
uv python install 3.12        # 下載並安裝指定版本
uv python install 3.11 3.12 # 一次安裝多個版本
uv python pin 3.12 # 建立 .python-version,鎖定專案用的版本
uv python list # 列出所有已安裝版本

有了這個功能,你不再需要 pyenv——uv 一個工具就涵蓋了 pyenv + venv + pip 的職責。Python 版本會在需要時自動下載,也可以手動預先安裝。

速度實測

以下是在同一台機器上安裝相同 50 個套件(含 numpy、pandas、django 等)的時間比較:

工具 環境建立 套件安裝 合計
venv + pip 2 秒 325 秒 327 秒
conda 5 秒 580 秒 585 秒
uv 2 秒 32 秒 34 秒

uv 快的原因是多層快取機制:套件 wheel 快取在本機後,後續安裝直接從快取取得,冷快取(第一次)和熱快取(重複安裝)的速度差異很大。這份測試沒有說明快取狀態與網速,數字僅供參考量級,實際差異因環境而異。

三種工具的選擇邏輯

這不是「uv 最好所以大家都該換」的問題,而是不同工具適合不同情境:

維持 venv + pip 的理由:

  • 專案在嚴格受管的企業環境,新工具需要審批流程
  • 維護老程式,現有 Makefile / CI 腳本深度依賴 pip 指令
  • 只需要基本功能,不值得引入額外複雜度

繼續用 conda 的理由:

  • 重度使用科學計算套件(numpy、scipy、CUDA toolkit),需要 conda 的預編譯 binary
  • 團隊的 conda 環境檔案(environment.yml)已累積多年,遷移成本高
  • 需要管理非 Python 系統依賴

切換到 uv 的理由:

  • 想用一個工具取代 pyenv + venv + pip,減少工具鏈複雜度
  • 新專案可以從頭採用 pyproject.toml 工作流
  • 在 CI 環境裡,安裝速度直接影響 pipeline 費用
  • 套件數量多,每天重複建立環境的時間累積可觀

從現有工作流遷移到 uv

最低風險的方式:先在 pip 相容模式下試水

1
2
3
4
# 只替換 pip install 這一步
uv venv .venv
source .venv/bin/activate
uv pip install -r requirements.txt

行為和 pip 幾乎相同,速度明顯提升,風險低。

進一步採用專案管理模式(新專案):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
uv init my-project
cd my-project

# 新增依賴
uv add fastapi uvicorn

# 新增開發用依賴
uv add --dev pytest ruff

# 同步環境(適合 CI 或新機器)
uv sync

# 執行腳本(不用手動 activate)
uv run python main.py
uv run pytest

uv.lock 是跨平台的鎖定檔,應該加入版控。新成員拉下 repo 後只需執行 uv sync,uv 會自動處理 Python 版本和所有依賴。

在 conda 環境旁邊使用 uv:

如果專案依賴 conda 提供的非 Python binary(例如 CUDA、Intel MKL),可以繼續用 conda 管理系統層依賴,只把 Python 套件管理這層換成 uv。兩者並不互斥。

結語

venv 的定位是隔離 Python 環境,conda 的強項是管理科學計算的系統依賴,uv 則是把 pyenv + virtualenv + pip + pip-tools 的功能整合成一個工具。

如果你正在起一個新的 Python 專案,uv 的 init → add → sync 工作流值得試一次——安裝速度快只是附帶效果,整套工作流的一致性才是更大的收益。