Python uv 套件管理器 2026:比 pip 快 10 倍的依賴管理終極指南
Python 依賴管理的至暗時刻
每個 Python 開發者都經歷過這些痛苦:
- pip 安裝慢如蝸牛:一個 Django 專案
pip install動輒幾分鐘,依賴解析卡在Collecting階段讓人抓狂 - poetry 設定複雜如天書:
pyproject.toml的依賴分組、extras、source 設定讓人頭大,lock 檔案衝突更是家常便飯 - venv 手動管理繁瑣:
python -m venv .venv、source .venv/bin/activate、deactivate……每個專案都要重複這套流程 - Python 版本切換混亂:pyenv、conda、系統 Python 互相打架,
which python永遠不知道指向哪個 - 依賴鎖定不可靠:
requirements.txt沒有鎖定檔案,pip freeze > requirements.txt產生的依賴包含間接依賴,環境無法重現
2024 年,Astral 團隊(ruff 的創造者)推出了 uv——一個用 Rust 編寫的 Python 套件管理器,速度比 pip 快 10-100 倍。到 2026 年,uv 已經成為 Python 生態中最受矚目的套件管理工具,支援專案管理、虛擬環境、Python 版本管理、Monorepo 工作區等全棧能力。
本文將從核心概念出發,透過 5 大實戰模式,帶你全面掌握 uv 的使用。
核心概念速查
| 概念 | 說明 | 對應命令 |
|---|---|---|
| 專案管理 | 初始化專案、管理依賴宣告 | uv init、uv add、uv remove |
| 虛擬環境 | 自動建立和管理 .venv | uv venv、uv sync |
| Python 版本管理 | 安裝和切換 Python 直譯器 | uv python install、uv python pin |
| 依賴鎖定 | 產生可重現的鎖定檔案 | uv lock(自動產生 uv.lock) |
| 依賴解析 | 高效能解析依賴樹 | 內建 Rust 解析器,10-100x 速度提升 |
| 工作區 | Monorepo 多套件管理 | uv workspace |
| 工具執行 | 臨時安裝並執行 CLI 工具 | uv tool run、uvx |
| 腳本執行 | 內聯依賴宣告並執行腳本 | uv run script.py |
| 快取管理 | 全域套件快取,避免重複下載 | uv cache |
| 匯出依賴 | 匯出為 requirements.txt 格式 | uv export |
五大核心挑戰分析
挑戰一:依賴解析速度
pip 使用回溯解析演算法,複雜依賴圖可能需要數分鐘甚至解析失敗。uv 採用基於 SAT 求解器的高效能解析器,通常在毫秒級完成解析。
挑戰二:環境一致性
requirements.txt 不包含完整的依賴鎖定資訊,不同機器安裝結果可能不同。uv 的 uv.lock 鎖定檔案記錄完整的依賴樹雜湊,確保任何環境都能精確重現。
挑戰三:Python 版本碎片化
不同專案需要不同 Python 版本,pyenv + venv 的組合設定繁瑣。uv 內建 Python 版本管理,一條命令安裝切換,無需額外工具。
挑戰四:Monorepo 依賴共享
多個子套件之間有內部依賴關係,傳統方案需要手動發佈到私有 PyPI 或使用 pip install -e。uv workspace 原生支援 Monorepo,子套件之間自動連結。
挑戰五:CI/CD 快取效率
pip 在 CI 中每次都要重新下載依賴,即使有快取也經常 cache miss。uv 的全域快取 + 內容定址機制讓 CI 快取命中率接近 100%。
方案一:uv 安裝與專案初始化
安裝 uv
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# 使用 pip 安裝(不推薦,僅作備用)
pip install uv
# 使用 Homebrew
brew install uv
# 驗證安裝
uv --version
# uv 0.7.12 (2026 年最新穩定版)
專案初始化
# 建立新專案
uv init my-project
cd my-project
# 查看專案結構
# my-project/
# ├── .python-version # Python 版本鎖定
# ├── pyproject.toml # 專案設定和依賴宣告
# ├── uv.lock # 依賴鎖定檔案(自動產生)
# ├── hello.py # 範例入口檔案
# └── .venv/ # 虛擬環境(自動建立)
依賴管理
# 新增依賴
uv add fastapi
uv add "sqlalchemy>=2.0"
uv add --dev pytest
uv add --dev ruff
# 新增可選依賴組
uv add --optional ml torch
# 移除依賴
uv remove pytest
# 同步依賴(安裝 pyproject.toml 中宣告的所有依賴)
uv sync
# 僅同步正式依賴(排除 dev)
uv sync --no-dev
# 同步指定分組
uv sync --group ml
pyproject.toml 結構
[project]
name = "my-project"
version = "0.1.0"
description = "A modern Python project"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.115.0",
"sqlalchemy>=2.0",
]
[project.optional-dependencies]
ml = [
"torch>=2.5",
"transformers>=4.45",
]
[tool.uv]
dev-dependencies = [
"pytest>=8.0",
"ruff>=0.8",
]
[tool.uv.sources]
my-private-pkg = { git = "https://github.com/myorg/my-private-pkg.git", tag = "v1.0.0" }
執行專案
# 在虛擬環境中執行腳本
uv run python hello.py
# 執行模組
uv run python -m my_project.main
# 執行帶內聯依賴宣告的腳本
uv run --with requests python fetch_data.py
方案二:虛擬環境與 Python 版本管理
虛擬環境管理
# 建立虛擬環境(預設使用 .venv 目錄)
uv venv
# 指定 Python 版本建立
uv venv --python 3.12
# 指定虛擬環境路徑
uv venv /path/to/.venv
# 啟用虛擬環境
# macOS / Linux
source .venv/bin/activate
# Windows
.venv\Scripts\activate
# uv sync 會自動建立虛擬環境
uv sync
Python 版本管理
# 查看可用 Python 版本
uv python list
# 安裝指定 Python 版本
uv python install 3.12
uv python install 3.13
# 安裝特定實作
uv python install pypy3.10
uv python install graalpy3.11
# 固定專案 Python 版本(寫入 .python-version)
uv python pin 3.12
# 查看已安裝版本
uv python list --only-installed
# 查找 Python 直譯器路徑
uv python find 3.12
# 臨時使用指定版本執行
uv run --python 3.13 python --version
.python-version 檔案
3.12
這個檔案會被 uv 自動讀取,確保團隊成員使用一致的 Python 版本。搭配 uv sync,新人 clone 專案後只需一條命令即可搭建完整環境。
多版本並行場景
# 專案 A 使用 Python 3.12
cd project-a
uv python pin 3.12
uv sync
# 專案 B 使用 Python 3.13
cd project-b
uv python pin 3.13
uv sync
# 兩個專案互不干擾,無需 pyenv 切換
方案三:從 pip/requirements.txt 和 poetry/pyproject.toml 遷移
從 pip + requirements.txt 遷移
# 方式一:直接在現有專案中初始化
cd existing-project
uv init
# uv 會偵測到已有的 requirements.txt 並自動匯入
# 方式二:手動匯入依賴
uv add $(cat requirements.txt | grep -v "^#" | grep -v "^$" | tr "\n" " ")
# 方式三:使用 uv pip 相容模式(過渡期使用)
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt
# 匯出回 requirements.txt 格式
uv export > requirements.txt
uv export --no-dev > requirements-prod.txt
從 poetry 遷移
# uv 直接讀取 poetry 的 pyproject.toml
cd poetry-project
uv init
# uv 會自動識別 [tool.poetry.dependencies] 並遷移
# 手動遷移步驟
# 1. 備份 poetry.lock
cp poetry.lock poetry.lock.bak
# 2. 將 poetry 依賴格式轉為 PEP 621 格式
# poetry 格式:
# [tool.poetry.dependencies]
# fastapi = "^0.115.0"
# PEP 621 格式:
# [project]
# dependencies = ["fastapi>=0.115.0"]
# 3. 產生 uv.lock
uv lock
# 4. 同步依賴
uv sync
poetry 到 uv 的 pyproject.toml 轉換腳本
import tomllib
import tomli_w
from pathlib import Path
def migrate_poetry_to_uv(pyproject_path: str = "pyproject.toml"):
""將 poetry 格式的 pyproject.toml 轉換為 uv 相容格式""
path = Path(pyproject_path)
data = tomllib.loads(path.read_text(encoding="utf-8"))
poetry_deps = data.get("TOOL", {}).get("poetry", {}).get("dependencies", {})
poetry_dev_deps = (
data.get("TOOL", {})
.get("poetry", {})
.get("group", {})
.get("dev", {})
.get("dependencies", {})
)
def convert_version(version_spec: str) -> str:
if isinstance(version_spec, dict):
return version_spec.get("version", "*")
if version_spec.startswith("^"):
base = version_spec[1:]
parts = base.split(".")
upper = f"{int(parts[0]) + 1}.0.0"
return f">={base},<{upper}"
if version_spec.startswith("~"):
base = version_spec[1:]
parts = base.split(".")
upper = f"{parts[0]}.{int(parts[1]) + 1}.0"
return f">={base},<{upper}"
return version_spec
dependencies = []
for name, version in poetry_deps.items():
if name == "python":
data.setdefault("project", {})["requires-python"] = f">={version}"
continue
dep = convert_version(version)
dependencies.append(f"{name}{dep}" if dep != "*" else name)
data.setdefault("project", {})["dependencies"] = dependencies
dev_dependencies = []
for name, version in poetry_dev_deps.items():
dep = convert_version(version)
dev_dependencies.append(f"{name}{dep}" if dep != "*" else name)
if dev_dependencies:
data.setdefault("TOOL", {}).setdefault("uv", {})[
"dev-dependencies"
] = dev_dependencies
if "poetry" in data.get("TOOL", {}):
del data["TOOL"]["poetry"]
path.write_text(tomli_w.dumps(data), encoding="utf-8")
print(f"遷移完成: {dependencies=}, {dev_dependencies=}")
if __name__ == "__main__":
migrate_poetry_to_uv()
從 pipenv 遷移
# 匯出 Pipfile 依賴為 requirements.txt
pipenv requirements > requirements.txt
# 使用 uv 初始化並匯入
uv init
uv add $(cat requirements.txt | tr "\n" " ")
uv sync
方案四:Monorepo 與工作區管理
工作區初始化
# 建立 Monorepo 根目錄
mkdir my-monorepo && cd my-monorepo
uv init --workspace
# 建立子套件
uv init --package libs/core
uv init --package libs/api
uv init --package apps/web
# 專案結構
# my-monorepo/
# ├── pyproject.toml # 工作區根設定
# ├── uv.lock # 全域鎖定檔案(統一管理)
# ├── libs/
# │ ├── core/
# │ │ ├── pyproject.toml
# │ │ └── src/core/
# │ └── api/
# │ ├── pyproject.toml
# │ └── src/api/
# └── apps/
# └── web/
# ├── pyproject.toml
# └── src/web/
根 pyproject.toml 設定
[tool.uv.workspace]
members = [
"libs/core",
"libs/api",
"apps/web",
]
[tool.uv.sources]
core = { workspace = true }
api = { workspace = true }
子套件 pyproject.toml
# libs/core/pyproject.toml
[project]
name = "core"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"pydantic>=2.9",
]
# libs/api/pyproject.toml
[project]
name = "api"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"core",
"fastapi>=0.115.0",
]
# apps/web/pyproject.toml
[project]
name = "web"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"core",
"api",
"uvicorn>=0.32.0",
]
工作區操作
# 同步整個工作區
uv sync
# 僅同步指定子套件
uv sync --package api
# 在指定子套件中執行命令
uv run --package api python -m api.main
# 為指定子套件新增依賴
uv add --package api httpx
# 建置指定子套件
uv build --package core
# 發佈指定子套件
uv publish --package core
工作區依賴圖驗證
# 查看依賴樹
uv tree
# 檢查依賴衝突
uv lock --check
# 更新指定依賴
uv lock --upgrade-package fastapi
方案五:CI/CD 整合與 Docker 最佳化
GitHub Actions 整合
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Set up Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --frozen
- name: Run linter
run: uv run ruff check .
- name: Run tests
run: uv run pytest --cov=src --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
GitLab CI 整合
# .gitlab-ci.yml
stages:
- test
- build
test:
stage: test
image: python:3.12-slim
before_script:
- pip install uv
- uv python install 3.12
- uv sync --frozen
script:
- uv run ruff check .
- uv run pytest --cov=src
cache:
key:
files:
- uv.lock
paths:
- .venv/
- ~/.cache/uv/
build:
stage: build
image: python:3.12-slim
before_script:
- pip install uv
script:
- uv build
artifacts:
paths:
- dist/
Docker 多階段建置最佳化
# Dockerfile
FROM ghcr.io/astral-sh/uv:latest AS uv
FROM python:3.12-slim AS deps
COPY --from=uv /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-install-project --no-dev
FROM python:3.12-slim AS runtime
WORKDIR /app
COPY --from=deps /app/.venv /app/.venv
COPY . .
ENV PATH="/app/.venv/bin:$PATH"
ENV VIRTUAL_ENV="/app/.venv"
CMD ["python", "-m", "my_project.main"]
Docker Compose 開發環境
# docker-compose.yml
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- .:/app
- uv-cache:/root/.cache/uv
environment:
- PYTHONUNBUFFERED=1
command: uv run uvicorn my_project.main:app --host 0.0.0.0 --reload
volumes:
uv-cache:
CI 快取最佳化技巧
# 使用 --frozen 確保不修改鎖定檔案(CI 環境必須)
uv sync --frozen
# 使用 --no-dev 減少安裝量
uv sync --frozen --no-dev
# 離線安裝(依賴已快取時)
uv sync --frozen --offline
常見陷阱指南
陷阱一:混用 pip 和 uv
❌ 在 uv 管理的專案中用 pip install 安裝依賴,繞過 uv 的依賴管理
✅ 始終使用 uv add 新增依賴,uv sync 同步環境。如需臨時安裝,用 uv pip install(相容模式)
陷阱二:忽略 uv.lock 提交
❌ 將 uv.lock 加入 .gitignore,導致團隊成員依賴版本不一致
✅ 將 uv.lock 提交到版本控制,確保所有環境使用相同的依賴版本。CI 中使用 --frozen 防止意外更新
陷阱三:忘記固定 Python 版本
❌ 不設定 .python-version,不同開發者使用不同 Python 版本導致相容性問題
✅ 使用 uv python pin 3.12 固定版本,並將 .python-version 提交到倉庫
陷阱四:全域安裝污染
❌ 使用 uv tool install 安裝大量全域工具,版本衝突難以排查
✅ 專案級工具使用 uv run --with 臨時安裝執行;全域工具僅安裝高頻使用的(如 ruff、black)
陷阱五:Docker 中不利用快取層
❌ 先 COPY 全部程式碼再 uv sync,每次程式碼變更都重新安裝依賴
✅ 先 COPY pyproject.toml + uv.lock,再 uv sync,最後 COPY 程式碼。利用 Docker 快取層避免重複安裝
錯誤排錯表
| 錯誤現象 | 可能原因 | 解決方案 |
|---|---|---|
error: No virtual environment found |
未建立虛擬環境 | 執行 uv sync 或 uv venv 自動建立 |
error: Failed to download package |
網路問題或 PyPI 來源不可達 | 設定映像來源:uv pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple |
error: Python 3.12 not found |
未安裝對應 Python 版本 | 執行 uv python install 3.12 |
error: Lockfile is out of date |
pyproject.toml 更新但未重新 lock | 執行 uv lock 更新鎖定檔案 |
error: Resolution failed |
依賴版本衝突 | 檢查 pyproject.toml 中的版本約束,使用 uv tree 查看依賴樹 |
error: Package not found in workspace |
工作區成員設定錯誤 | 檢查 [tool.uv.workspace] 的 members 路徑 |
uv sync 速度慢 |
快取未命中或網路延遲 | 檢查快取目錄權限,設定映像來源,使用 --offline 模式 |
error: Hash mismatch |
依賴套件被竄改或快取損壞 | 執行 uv cache clean 清除快取後重試 |
error: Cannot activate venv |
虛擬環境損壞 | 刪除 .venv 目錄後重新 uv sync |
error: Unsupported Python version |
Python 版本不滿足 requires-python | 執行 uv python install 安裝滿足要求的版本 |
進階最佳化技巧
1. 映像來源加速
# 設定清華映像來源(台灣地區推薦)
uv pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 或在 pyproject.toml 中設定
# [tool.uv]
# index-url = "https://pypi.tuna.tsinghua.edu.cn/simple"
# 多來源設定(私有 PyPI + 公共來源)
# [tool.uv]
# extra-index-url = ["https://pypi.mycompany.com/simple/"]
2. 快取管理
# 查看快取資訊
uv cache dir
uv cache list
# 清除快取
uv cache clean
# 清除特定套件的快取
uv cache clean numpy
# 查看快取大小
du -sh $(uv cache dir)
3. 離線環境部署
# 匯出依賴到 vendor 目錄
uv export --no-dev > requirements.txt
uv pip download -r requirements.txt -d vendor/
# 離線安裝
uv pip install --no-index --find-links vendor/ -r requirements.txt
4. 腳本內聯依賴
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests>=2.32",
# "rich>=13.0",
# ]
# ///
import requests
from rich import print
response = requests.get("https://httpbin.org/json")
print(response.json())
# 直接執行,uv 自動安裝依賴
uv run script.py
5. 依賴安全稽核
# 檢查已知漏洞
uv audit
工具對比選型
| 維度 | uv | pip | poetry | pdm | conda |
|---|---|---|---|---|---|
| 依賴解析速度 | 極快(Rust) | 慢(回溯) | 中等 | 快 | 慢 |
| 虛擬環境管理 | 內建 | 需 venv | 內建 | 內建 | 內建 |
| Python 版本管理 | 內建 | 需 pyenv | 需 pyenv | 內建 | 內建 |
| 鎖定檔案 | uv.lock | 無 | poetry.lock | pdm.lock | 無 |
| Monorepo 支援 | 原生工作區 | 不支援 | 不支援 | 有限 | 不支援 |
| CI 快取友善 | 極好 | 一般 | 好 | 好 | 差 |
| 設定複雜度 | 低 | 低 | 高 | 中 | 高 |
| 生態成熟度 | 快速成長 | 最成熟 | 成熟 | 成長中 | 成熟 |
| 學習曲線 | 平緩 | 平緩 | 陡峭 | 中等 | 陡峭 |
| 套件數量 | PyPI 全量 | PyPI 全量 | PyPI 全量 | PyPI 全量 | Anaconda + PyPI |
| 跨語言支援 | 僅 Python | 僅 Python | 僅 Python | 僅 Python | 多語言(C/C++/R) |
| 推薦指數 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
選型建議:
- 新專案首選 → uv(全棧能力、極速體驗)
- 已有 poetry 專案 → 逐步遷移到 uv(相容讀取 poetry 設定)
- 資料科學/ML 專案 → uv + conda 互補(uv 管理純 Python 套件,conda 管理 C/C++ 依賴)
- 簡單腳本/一次性任務 → uv run(無需初始化專案)
相關工具推薦
在 Python 專案開發中,以下 工具庫 工具可以幫到你:
- JSON 格式化 — 格式化 API 回應和設定檔案,排查 pyproject.toml 中的 JSON 資料問題
- Hash 計算 — 計算依賴套件雜湊值,驗證下載完整性
- cURL 轉程式碼 — 將 API 請求一鍵轉為 Python 程式碼,快速建構 HTTP 客戶端
Python 依賴管理經歷了從
easy_install到pip,從requirements.txt到poetry.lock的漫長演進。uv 的出現不是簡單的替代,而是將 Rust 的高效能與 Python 的易用性完美結合,讓依賴管理從「不得不忍受的痛點」變成「幾乎無感的體驗」。2026 年,uv 已經準備好成為你的預設選擇。
本站提供瀏覽器本地工具,免註冊即可試用 →