uv 套件管理器教學 #03 專案管理:pyproject.toml 完全攻略

測驗:pyproject.toml 完全攻略

共 5 題,點選答案後會立即顯示結果

1. 執行 uv init my-project 後,哪個檔案是專案的核心設定檔?

  • A. .python-version
  • B. hello.py
  • C. pyproject.toml
  • D. README.md

2. 在 pyproject.toml 中,dependencies[dependency-groups] dev 的主要差別是什麼?

  • A. dependencies 只能放 Python 內建套件
  • B. dependencies 會在發布時包含,dev 不會
  • C. dev 只能放測試相關的套件
  • D. 沒有差別,只是命名不同

3. 執行 uv add requests 指令會做哪些事情?

  • A. 只更新 pyproject.toml
  • B. 只安裝套件到虛擬環境
  • C. 更新 pyproject.toml 和安裝套件
  • D. 更新 pyproject.toml、更新 uv.lock、安裝套件

4. uv.lock 鎖定檔的主要用途是什麼?

  • A. 記錄專案的名稱和版本
  • B. 鎖定 Python 版本不能更新
  • C. 記錄確切的依賴版本,確保環境一致
  • D. 防止其他人修改專案設定

5. uv run python main.py 相比直接執行 python main.py,多做了什麼?

  • A. 會自動建立新的 Python 檔案
  • B. 會自動檢查並同步虛擬環境和依賴
  • C. 會自動發布到 PyPI
  • D. 會自動執行測試

一句話說明

用一個設定檔管理整個 Python 專案:名稱、版本、依賴全都在這裡。

這篇要學什麼?

讀完這篇後,你會知道:

  • uv init 建立新專案時會產生什麼檔案
  • pyproject.toml 裡面每個區塊是什麼意思
  • 怎麼用 uv adduv remove 管理依賴
  • 開發用依賴(dev dependencies)和正式依賴的差別
  • uv.lock 鎖定檔在幹嘛

專案初始化:uv init

最小範例

uv init my-project
cd my-project

這會產生什麼?

my-project/
├── .gitignore      # Git 忽略清單
├── .python-version # Python 版本
├── README.md       # 專案說明
├── hello.py        # 範例程式
└── pyproject.toml  # 專案設定(重點!)
Code language: PHP (php)

逐行翻譯

uv init my-project   # 建立名為 my-project 的新專案資料夾,自動產生基本檔案結構
cd my-project        # 進入專案資料夾
Code language: PHP (php)

常見變化

AI 可能會這樣用:

變化 1:在目前資料夾初始化

uv init

翻譯:不指定名稱,就在目前資料夾建立專案

變化 2:建立函式庫專案

uv init --lib my-lib

翻譯:建立函式庫(library)專案,會有 src/ 資料夾結構

變化 3:建立可執行的套件

uv init --package my-cli

翻譯:建立可發布到 PyPI 的命令列工具專案


pyproject.toml 結構解析

30 秒範例

[project]
name = "my-project"
version = "0.1.0"
description = "我的專案"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    "requests>=2.31.0",
]

[dependency-groups]
dev = [
    "pytest>=8.0.0",
    "ruff>=0.1.0",
]
Code language: JavaScript (javascript)

核心區塊翻譯

區塊 意思
[project] 專案基本資訊:名稱、版本、依賴
name = "..." 專案名稱
version = "..." 版本號
requires-python = "..." 需要的 Python 版本
dependencies = [...] 正式依賴(發布時會包含)
[dependency-groups] 依賴群組(PEP 735 標準)
dev = [...] 開發依賴群組(uv 預設會安裝)

必看懂:dependencies vs dev

# 正式依賴 - 專案運行必須的套件
dependencies = [
    "requests>=2.31.0",
    "pydantic>=2.0.0",
]

# 開發依賴 - 只有開發時需要,發布時不包含
[dependency-groups]
dev = [
    "pytest>=8.0.0",
    "ruff>=0.1.0",
]
Code language: PHP (php)

白話翻譯

  • dependencies:使用者安裝你的套件時,這些會一起裝
  • dev:測試工具、程式碼檢查工具,使用者不需要

依賴管理:uv add / uv remove

新增依賴

# 新增正式依賴
uv add requests

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

# 新增到自訂群組
uv add --group lint ruff
Code language: PHP (php)

移除依賴

# 移除正式依賴
uv remove requests

# 移除開發依賴
uv remove --dev pytest
Code language: PHP (php)

這在幹嘛?

uv add requests

做了三件事

  1. pyproject.tomldependencies 加入 requests
  2. 更新 uv.lock 鎖定檔
  3. 在虛擬環境安裝套件

版本指定

# 指定最低版本
uv add "requests>=2.31.0"

# 指定版本範圍
uv add "requests>=2.31.0,<3.0.0"

# 指定確切版本
uv add "requests==2.31.0"
Code language: PHP (php)

常見變化

變化 1:從 Git 安裝

uv add git+https://github.com/user/repo.git
Code language: JavaScript (javascript)

翻譯:從 GitHub 直接安裝套件

變化 2:安裝本地套件

uv add ./path/to/local-package

翻譯:安裝你電腦上的另一個專案


uv.lock 鎖定檔

一句話說明

記錄「確切」安裝了哪些版本,讓所有人的環境一模一樣。

pyproject.toml vs uv.lock

檔案 內容 用途
pyproject.toml requests>=2.31.0 說「至少要 2.31.0」
uv.lock requests==2.32.3 記錄「實際裝了 2.32.3」

為什麼需要鎖定檔?

沒有鎖定檔

你的電腦:requests 2.32.3
同事電腦:requests 2.31.0  <-- 版本不同!
Code language: CSS (css)

有鎖定檔

你的電腦:requests 2.32.3
同事電腦:requests 2.32.3  <-- 一樣!
Code language: CSS (css)

常用指令

# 重新生成鎖定檔
uv lock

# 根據鎖定檔安裝(確保版本一致)
uv sync

# 檢查鎖定檔是否與 pyproject.toml 一致
uv lock --check
Code language: PHP (php)

Vibe Coder 檢查點

看到 uv.lock 時確認:

  • [ ] 這個檔案要加入 Git 版本控制
  • [ ] 不要手動編輯這個檔案
  • [ ] 如果安裝失敗,試試 uv lock 重新生成

執行專案:uv run

最小範例

uv run python hello.py
Code language: CSS (css)

這在幹嘛?

uv run 自動做這些事:

  1. 檢查 pyproject.toml 有沒有改
  2. 檢查 uv.lock 是否最新
  3. 確保虛擬環境有安裝所有依賴
  4. 然後才執行你的指令

常見用法

# 執行 Python 腳本
uv run python main.py

# 執行測試
uv run pytest

# 執行程式碼檢查
uv run ruff check .

# 啟動 Flask 開發伺服器
uv run flask run
Code language: PHP (php)

和直接執行的差別

# 傳統做法
source .venv/bin/activate   # 1. 先啟動虛擬環境
pip install -r requirements.txt  # 2. 安裝依賴
python main.py              # 3. 執行

# uv 做法
uv run python main.py       # 一行搞定,自動處理環境
Code language: PHP (php)

完整工作流程範例

情境:建立新的 FastAPI 專案

# 1. 初始化專案
uv init my-api
cd my-api

# 2. 新增依賴
uv add fastapi uvicorn

# 3. 新增開發依賴
uv add --dev pytest httpx

# 4. 執行開發伺服器
uv run uvicorn main:app --reload
Code language: PHP (php)

情境:加入現有專案開發

# 1. clone 專案
git clone https://github.com/xxx/project.git
cd project

# 2. 同步環境(根據 uv.lock 安裝所有依賴)
uv sync

# 3. 開始開發
uv run python main.py
Code language: PHP (php)

對 Vibe Coding 的幫助

學會這些概念後,你可以:

  • 更精準地下指令:告訴 AI「用 uv add 加入 xxx 套件到 dev dependencies」,AI 就會用正確的 --dev 參數
  • 更有效地 Review AI 產出:當 AI 修改 pyproject.toml 時,你知道它改了什麼區塊、會有什麼影響
  • 更快速地除錯:看到「找不到套件」錯誤時,知道要檢查 pyproject.tomluv.lock 是否同步

總結

這篇學到的重點:

指令/檔案 用途
uv init 建立新專案
pyproject.toml 專案設定檔
uv add 新增依賴
uv add --dev 新增開發依賴
uv remove 移除依賴
uv.lock 版本鎖定檔
uv run 執行指令(自動處理環境)

下一篇我們會介紹如何發布你的套件到 PyPI。

進階測驗:pyproject.toml 完全攻略

測驗目標:驗證你是否能在實際情境中應用所學。
共 5 題,包含情境題與錯誤診斷題。

1. 你正在開發一個 Web API,需要加入 pytest 來寫測試。你希望這個套件只在開發時使用,不要在使用者安裝你的套件時一起裝。應該執行哪個指令? 情境題

  • A. uv add pytest
  • B. uv add --group test pytest
  • C. uv add --dev pytest
  • D. uv install pytest --save-dev

2. 同事 clone 了你的專案後執行 uv run python main.py,但出現以下錯誤: 錯誤診斷

ModuleNotFoundError: No module named ‘requests’

專案的 pyproject.toml 明明有寫 dependencies = ["requests>=2.31.0"],最可能的原因是什麼?

  • A. requests 套件已經從 PyPI 下架了
  • B. uv.lock 檔案沒有加入版本控制,同事的環境無法正確同步
  • C. 同事的 Python 版本太舊
  • D. 需要先執行 pip install requests

3. 你想建立一個可以發布到 PyPI 的命令列工具專案,應該使用哪個初始化指令? 情境題

  • A. uv init my-cli
  • B. uv init --lib my-cli
  • C. uv init --app my-cli
  • D. uv init --package my-cli

4. 你更新了 pyproject.toml 加入新的依賴,但執行 uv run 時出現警告: 錯誤診斷

warning: The lockfile at `uv.lock` is out of date

這個警告表示什麼,應該怎麼處理?

  • A. uv.lock 檔案損壞了,需要刪除重來
  • B. Python 版本需要更新
  • C. pyproject.toml 有變更但 uv.lock 還沒更新,執行 uv lock 更新鎖定檔
  • D. 需要重新執行 uv init 初始化專案

5. 看到以下 pyproject.toml 內容,哪個敘述是正確的? 情境題

[project] name = “my-api” version = “1.0.0” dependencies = [ “fastapi>=0.100.0”, “uvicorn>=0.23.0”, ] [dependency-groups] dev = [ “pytest>=8.0.0”, “httpx>=0.25.0”, ]
  • A. 使用者安裝 my-api 時會同時安裝 pytest 和 httpx
  • B. 使用者安裝 my-api 時只會安裝 fastapi 和 uvicorn
  • C. 執行 uv sync 時不會安裝 pytest
  • D. dev 群組的套件版本不能指定範圍

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *