測驗:pyproject.toml 完全攻略
共 5 題,點選答案後會立即顯示結果
1. 執行 uv init my-project 後,哪個檔案是專案的核心設定檔?
2. 在 pyproject.toml 中,dependencies 和 [dependency-groups] dev 的主要差別是什麼?
3. 執行 uv add requests 指令會做哪些事情?
4. uv.lock 鎖定檔的主要用途是什麼?
5. uv run python main.py 相比直接執行 python main.py,多做了什麼?
一句話說明
用一個設定檔管理整個 Python 專案:名稱、版本、依賴全都在這裡。
這篇要學什麼?
讀完這篇後,你會知道:
- 用
uv init建立新專案時會產生什麼檔案 pyproject.toml裡面每個區塊是什麼意思- 怎麼用
uv add和uv 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
做了三件事:
- 在
pyproject.toml的dependencies加入requests - 更新
uv.lock鎖定檔 - 在虛擬環境安裝套件
版本指定
# 指定最低版本
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 自動做這些事:
- 檢查
pyproject.toml有沒有改 - 檢查
uv.lock是否最新 - 確保虛擬環境有安裝所有依賴
- 然後才執行你的指令
常見用法
# 執行 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.toml和uv.lock是否同步
總結
這篇學到的重點:
| 指令/檔案 | 用途 |
|---|---|
uv init |
建立新專案 |
pyproject.toml |
專案設定檔 |
uv add |
新增依賴 |
uv add --dev |
新增開發依賴 |
uv remove |
移除依賴 |
uv.lock |
版本鎖定檔 |
uv run |
執行指令(自動處理環境) |
下一篇我們會介紹如何發布你的套件到 PyPI。
進階測驗:pyproject.toml 完全攻略
測驗目標:驗證你是否能在實際情境中應用所學。
共 5 題,包含情境題與錯誤診斷題。
共 5 題,包含情境題與錯誤診斷題。
1. 你正在開發一個 Web API,需要加入 pytest 來寫測試。你希望這個套件只在開發時使用,不要在使用者安裝你的套件時一起裝。應該執行哪個指令? 情境題
2. 同事 clone 了你的專案後執行 uv run python main.py,但出現以下錯誤: 錯誤診斷
ModuleNotFoundError: No module named ‘requests’
專案的 pyproject.toml 明明有寫 dependencies = ["requests>=2.31.0"],最可能的原因是什麼?
3. 你想建立一個可以發布到 PyPI 的命令列工具專案,應該使用哪個初始化指令? 情境題
4. 你更新了 pyproject.toml 加入新的依賴,但執行 uv run 時出現警告: 錯誤診斷
warning: The lockfile at `uv.lock` is out of date
這個警告表示什麼,應該怎麼處理?
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”,
]