TOML 近年來在軟體開發領域,尤其是在 Python 社群中,變得越來越重要。
1. TOML 格式的用途是什麼?
TOML 的全名是 Tom’s Obvious, Minimal Language (湯姆的顯而易見的、最小化的語言)。
它的主要用途是作為設定檔 (Configuration File) 的格式。設計 TOML 的核心目標是:
- 人類易讀性 (Human-Readable):TOML 的語法被設計得非常直觀,一眼就能看懂鍵值關係和資料結構,就像在閱讀一個
.ini
檔案,但功能更強大。 - 易於解析 (Easy to Parse):它的結構清晰,讓程式可以非常簡單、 unambiguous 地將其解析成對應的資料結構(如字典或雜湊表)。
- 語意明確 (Unambiguous):TOML 的規範很嚴格,避免了像 YAML 那樣因為縮排或語法細節而導致的解析歧義。
簡單來說,TOML 致力於成為一個「更好」的設定檔格式。
常見應用場景:
- Python 專案:自從 PEP 518 和後續提案的推廣,
pyproject.toml
已經成為現代 Python 專案的標準設定檔,用來管理專案的建構依賴 (build dependencies)、專案元數據 (metadata) 和各種工具(如black
,pytest
,ruff
)的設定。這也是您在上一個問題中看到的用法。 - Rust 語言:Rust 的套件管理器 Cargo 使用
Cargo.toml
作為其專案的清單檔案 (manifest file),用來定義套件資訊、依賴項等。 - 靜態網站生成器:許多靜態網站生成器(如 Hugo)也支援使用 TOML 來撰寫網站的設定。
- 各種應用程式設定:任何需要一個清晰設定檔的應用程式,都可以選擇 TOML。
與其他格式相比:
- 相較於 JSON:TOML 更適合手動編寫和維護,因為它允許註解,且語法更寬鬆(例如,尾隨逗號是允許的)。JSON 則更適合做為機器間的資料交換格式。
- 相較於 YAML:TOML 的語法更簡單、更嚴格,避免了 YAML 複雜的縮排和語法特性可能導致的混淆和安全風險(例如 “Norway Problem”)。
- 相較於 INI:TOML 可以視為 INI 的超集 (superset),它支援巢狀結構、陣列、多種資料型別,功能遠比傳統 INI 格式強大。
2. TOML 是誰發明的?
TOML 的發明者是 湯姆·普雷斯頓-維爾納 (Tom Preston-Werner)。
他是一位在開發者社群中非常有影響力的人物,最為人所知的身分是 GitHub 的共同創辦人 (Co-founder) 兼前任執行長 (CEO)。他創造 TOML 的初衷,就是希望有一個簡單、明確,且不會引起混淆的設定檔格式。
3. TOML 的基本寫法與架構
TOML 的結構主要由以下幾個部分組成:
- 鍵值對 (Key-Value Pairs)to
- 註解 (Comments)
- 資料表 / 區塊 (Tables)
- 資料表陣列 (Arrays of Tables)
以下是相關的語法說明和範例:
基本架構範例
# 這是一個 TOML 文件的頂層。
# 井號 (#) 開頭的都是註解。
# 1. 頂層的鍵值對
title = "TOML 範例"
version = 1.0
is_production = false
# 2. 資料型別
# 字串
author = "Tom Preston-Werner"
# 整數
year = 2024
# 浮點數
pi = 3.14159
# 布林值
enabled = true
# 日期與時間 (遵循 RFC 3339 標準)
release_date = 2025-09-03T16:49:12+08:00
# 3. 陣列 (Arrays)
ports = [ 8001, 8002, 8003 ]
developers = [ "Alice", "Bob", "Charlie" ]
# 陣列可以包含不同類型,但不建議這麼做
mixed_data = [ 1, "test", true ]
# 4. 資料表 / 區塊 (Table) - 用於建立巢狀結構
# 語法: [table_name]
[database]
server = "192.168.1.1"
port = 5432
user = "admin"
password = "password123"
# 5. 巢狀資料表 (Nested Tables)
# 語法: [table.sub_table]
[owner]
name = "John Doe"
organization = "ACME Corp"
[owner.contact] # 這裡的 contact 就隸屬於 owner 之下
email = "john.doe@acme.com"
phone = "02-1234-5678"
# 等同於以下的 JSON 結構:
# {
# "owner": {
# "name": "John Doe",
# "organization": "ACME Corp",
# "contact": {
# "email": "john.doe@acme.com",
# "phone": "02-1234-5678"
# }
# }
# }
# 6. 資料表陣列 (Array of Tables) - 用於表示一組物件
# 語法: [[table_name]]
# 每次重複使用 [[table_name]] 就代表陣列中的一個新物件
[[products]]
name = "Laptop"
sku = "PROD-001"
price = 45000.0
[[products]]
name = "Mouse"
sku = "PROD-002"
price = 1200.0
# 等同於以下的 JSON 結構:
# {
# "products": [
# { "name": "Laptop", "sku": "PROD-001", "price": 45000.0 },
# { "name": "Mouse", "sku": "PROD-002", "price": 1200.0 }
# ]
# }
# 7. 多行字串
# 使用三個雙引號 (""")
multi_line_string = """
這是一段可以換行的文字。"""
# 8. 字面量字串 (Literal Strings)
# 使用單引號,裡面的特殊字元不會被轉義
path = 'C:\Users\admin\Documents' # \U 和 \D 不會被當作跳脫字元
總結
特性說明用途作為一個人類易讀、電腦易解析的設定檔格式。
核心語法key = value
,簡單明瞭。
註解使用 #
符號。
巢狀結構使用 [table_name]
和 [table.sub_table]
建立階層。
物件列表使用 [[array_of_tables]]
語法來定義一組擁有相同結構的物件。
優點語法清晰、無歧義、功能比 INI 強大、比 YAML 簡單安全。
主要應用Python 的 pyproject.toml
、Rust 的 Cargo.toml
等。