本文 AI 產出,尚未審核

Python 基礎概念:requirements.txtpyproject.toml

簡介

在 Python 開發的過程中,套件管理是不可或缺的環節。無論是單純的腳本還是大型的 Web 應用,都會依賴第三方套件來加速開發、提升功能。若沒有一套規範的方式記錄與安裝這些套件,團隊協作、部署到測試或正式環境時就會出現「在我機器上可以跑」的尷尬情況。

傳統上,Python 社群使用 requirements.txt 來列出所有相依套件;而在近年來,隨著 PEP 517/518 的推廣與 PEP 621project 表格) 的標準化,pyproject.toml 正逐漸成為 統一的建置與相依描述檔。本篇文章將從概念、實作、常見陷阱到最佳實務,完整說明這兩種檔案的使用方式,幫助初學者快速上手,也讓中級開發者在專案管理上更得心應手。


核心概念

1. requirements.txt 的定位

requirements.txt 是一個純文字檔,每一行寫入 套件名稱 + 版本規則,常見的格式如下:

requests==2.28.1
numpy>=1.23,<2.0
flask
  • 優點

    • 簡潔、易讀,幾乎所有的 Python 開發工具都支援。
    • 直接與 pip install -r requirements.txt 結合,快速安裝整批套件。
  • 限制

    • 只描述 執行階段相依,不包含建置工具(如 setuptoolswheel)或開發需求(如 pytest)。
    • 版本衝突的解決需要手動調整,缺乏結構化資訊。

2. 為什麼需要 pyproject.toml

PEP 518(2016)首次引入 pyproject.toml,作為 建置系統的配置檔。PEP 621(2021)則擴充此檔案,使其能夠完整描述 專案的元資料與相依,取代 setup.pysetup.cfgrequirements.txt 的部分功能。

pyproject.tomlTOML(Tom's Obvious Minimal Language)格式,具備:

  • 結構化的段落(tables)與子段落(sub‑tables)。
  • 支援多種工具的設定(如 blackisortmypy)。
  • 可同時記錄 執行時相依開發時相依[project.optional-dependencies])以及 建置後端[build-system])。

3. 基本結構比較

檔案 主要用途 主要語法 支援的相依類型
requirements.txt 快速安裝執行時相依 pkg==version>=< 執行時相依
pyproject.toml 建置、執行、開發相依全掌握 TOML 表格與鍵值 執行時、開發時、建置後端

程式碼範例

以下示範三個常見情境,讓你了解兩者如何搭配使用,並掌握實務技巧。

範例 1:最簡單的 requirements.txt

# requirements.txt
requests==2.28.1          # 固定版本,避免相容性問題
pandas>=1.5,<2.0          # 允許次要更新
flask                     # 未指定版本,安裝最新

安裝方式:

pip install -r requirements.txt

小技巧:在 CI/CD pipeline 中,使用 pip install --no-cache-dir -r requirements.txt 可以避免快取造成的舊版套件問題。


範例 2:使用 pyproject.toml 定義執行時與開發時相依

# pyproject.toml
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "awesome-tool"
version = "0.1.0"
description = "示範用的小工具"
authors = [{name = "Jane Doe", email = "jane@example.com"}]
requires-python = ">=3.9"

# 執行時相依
dependencies = [
    "requests>=2.28,<3.0",
    "pandas>=1.5,<2.0"
]

# 開發時相依(測試、格式化、靜態分析)
[project.optional-dependencies]
dev = [
    "pytest>=7.0",
    "black>=22.0",
    "mypy>=0.950"
]

# 讓工具(如 black)可以直接讀取設定
[tool.black]
line-length = 88
target-version = ["py39"]

安裝所有相依(包含開發時套件):

# 先安裝建置後端
pip install -e .[dev]   # -e 表示 editable 安裝,[dev] 會安裝 optional-dependencies

說明-e .[dev] 會把當前目錄作為可編輯的套件安裝,同時拉出 dev 群組的相依。若只想安裝執行時相依,使用 pip install . 即可。


範例 3:在 requirements.txt 中引用 pyproject.toml 產生的凍結檔

在大型專案中,我們常會把 開發環境dev)與 部署環境prod)分開管理。pip-tools 提供 pip-compile,可以將 pyproject.toml 轉換為凍結版 requirements.txt

# 安裝 pip-tools
pip install pip-tools

# 產生凍結檔(只保留執行時相依)
pip-compile pyproject.toml --output-file requirements.txt

產生的 requirements.txt 可能長這樣:

# This file is autogenerated by pip-compile
pandas==1.5.3            # via -r pyproject.toml
requests==2.28.2         # via -r pyproject.toml

之後的部署只需要:

pip install -r requirements.txt

優點:凍結檔保證每次部署使用 相同 版本,避免因套件更新而產生不可預期的錯誤。


範例 4:使用 poetry 管理 pyproject.toml

poetry 是一套 全功能的套件管理工具,它直接操作 pyproject.toml,不需要額外的 requirements.txt

# 初始化專案
poetry init

# 加入執行時相依
poetry add requests pandas

# 加入開發時相依
poetry add --dev pytest black

poetry.lock 會自動產生,確保版本凍結。部署時:

poetry install --no-dev   # 只安裝執行時相依

範例 5:在 CI 中同時使用 requirements.txtpyproject.toml

# .github/workflows/python-ci.yml
name: Python CI

on:
  push:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Install build deps
        run: pip install --upgrade pip setuptools wheel

      - name: Install project (editable) + dev deps
        run: pip install -e .[dev]

      - name: Run tests
        run: pytest

這個工作流程示範了 直接以 pyproject.toml[project.optional-dependencies] 方式安裝開發相依,省去維護額外的 requirements-dev.txt


常見陷阱與最佳實踐

陷阱 描述 解決方案 / 最佳實踐
版本衝突 多個套件要求不同的版本範圍,導致安裝失敗。 使用 pip-compilepoetry 產生凍結檔,或在 pyproject.toml 中明確指定兼容範圍。
忘記同步 修改 pyproject.toml 後,未更新 requirements.txt,部署仍使用舊版本。 在 CI/CD 前加入 pip-compile 步驟,或直接改用 pyproject.toml + poetry,省去同步工作。
將開發套件寫入 requirements.txt 部署環境會安裝不必要的測試或格式化工具,增加映像檔大小。 把開發套件放在 [project.optional-dependencies](或 dev-dependencies),僅在本機或 CI 使用。
使用過於寬鬆的版本規則 (>= 無上限) 未來某個重大更新可能破壞相容性。 建議使用 ~=, >= + <==,將上限明確限制在次要版本範圍內。
直接編輯 requirements.txt 而不檢查依賴樹 可能遺漏隱含依賴,導致執行時錯誤。 使用 pipdeptreepoetry show --tree 檢視完整依賴圖。

最佳實踐總結

  1. pyproject.toml 為主:將專案元資料、執行時相依、開發相依統一管理。
  2. 凍結版本:在部署前產生 requirements.txt(或使用 poetry.lock)以保證環境一致性。
  3. 分離環境:使用虛擬環境(venvconda)或容器化(Docker)搭配上述檔案,避免系統套件污染。
  4. 自動化檢查:將相依衝突檢測、凍結檔產生寫入 CI,確保每次提交都通過驗證。

實際應用場景

場景 需求 推薦做法
個人小腳本 快速安裝少量套件 直接寫 requirements.txtpip install -r requirements.txt
團隊開發的 Flask API 多人協作、需區分開發/測試/部署 使用 pyproject.toml + poetry,將 dev 群組列出測試、格式化套件;在 CI 中 poetry install --no-dev
資料科學專案 大量相依、需 reproducible 環境 pyproject.toml + pip-compile 產生凍結 requirements.txt,配合 Dockerfile 建立可重現的映像檔
第三方套件發布 必須提供 setup.cfg/pyproject.toml 給使用者 完全使用 pyproject.toml(PEP 621),避免 setup.py,同時在 README 中說明 pip install .pip install package-name 即可
CI/CD 自動化 每次 commit 必須測試相依完整性 在 workflow 中加入 pip install -U pip-tools && pip-compile pyproject.toml -o requirements.txt && pip install -r requirements.txt,確保相依凍結且一致

總結

  • requirements.txt最簡潔 的相依清單,適合快速安裝或小型專案。
  • pyproject.toml 則是 現代化、結構化 的專案描述檔,除了能管理執行時相依,還能同時記錄建置工具、開發相依與其他工具設定,讓專案更具可維護性。
  • 在實務上,結合兩者 的最佳方式是:以 pyproject.toml 為唯一真相來源,利用 pip-toolspoetry 產生凍結的 requirements.txt(或 poetry.lock),保證部署環境的可預測性。
  • 切記 明確版本限制分離開發與執行相依,並把相依管理流程寫入 CI/CD,這樣才能避免「本機跑得好」的常見問題。

透過本文的概念與範例,你已經掌握了在 Python 專案中正確使用 requirements.txtpyproject.toml 的方法。未來無論是個人腳本、資料分析工作流,或是大型 Web 服務,都能以一致、可靠的方式管理套件相依,讓開發、測試與部署變得更加順暢。祝你寫程式愉快,專案順利上線!