Python uv 套件管理器 2026:比 pip 快 10 倍的依賴管理終極指南

编程语言

Python 依賴管理的至暗時刻

每個 Python 開發者都經歷過這些痛苦:

  • pip 安裝慢如蝸牛:一個 Django 專案 pip install 動輒幾分鐘,依賴解析卡在 Collecting 階段讓人抓狂
  • poetry 設定複雜如天書pyproject.toml 的依賴分組、extras、source 設定讓人頭大,lock 檔案衝突更是家常便飯
  • venv 手動管理繁瑣python -m venv .venvsource .venv/bin/activatedeactivate……每個專案都要重複這套流程
  • 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 inituv adduv remove
虛擬環境 自動建立和管理 .venv uv venvuv sync
Python 版本管理 安裝和切換 Python 直譯器 uv python installuv python pin
依賴鎖定 產生可重現的鎖定檔案 uv lock(自動產生 uv.lock)
依賴解析 高效能解析依賴樹 內建 Rust 解析器,10-100x 速度提升
工作區 Monorepo 多套件管理 uv workspace
工具執行 臨時安裝並執行 CLI 工具 uv tool runuvx
腳本執行 內聯依賴宣告並執行腳本 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 syncuv 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_installpip,從 requirements.txtpoetry.lock 的漫長演進。uv 的出現不是簡單的替代,而是將 Rust 的高效能與 Python 的易用性完美結合,讓依賴管理從「不得不忍受的痛點」變成「幾乎無感的體驗」。2026 年,uv 已經準備好成為你的預設選擇。

本站提供瀏覽器本地工具,免註冊即可試用 →

#Python包管理#uv工具#pip替代#Python依赖管理#2026#编程语言