查看 Python 內建函數幫助(`help(sum)`、`help(id)`、`help(input)`)時,簽名末尾常出現一個單獨的斜線 `/`:
>> help(sum)
sum(iterable, start=0, /)
>>> help(id)
id(obj, /)
>>> help(input)
input(prompt=None, /)
但在自定義函數中直接寫 `def f(a, /):` 會報 `SyntaxError`(Python 3.7 及以下),或在 3.8+ 中合法但意圖不明。
**斜線 `/` 之前的所有參數必須以位置參數形式傳遞,不能使用關鍵字參數。** 這是 Python 3.8 (PEP 570) 引入的新語法,用於在函數定義中強制指定參數傳遞方式。
def func(pos_only1, pos_only2, /, pos_or_kw, *, kw_only1, kw_only2):
pass
| 區域 | 參數 | 調用方式 | 說明 |
|---|---|---|---|
| `/` 之前 | pos_only1, pos_only2 | 僅位置參數 | 調用時**不能**寫 `pos_only1=值` |
| func(1, 2, ...) | 順序固定,必須傳值 | ||
| `/` 到 `*` 之間 | pos_or_kw | 位置或關鍵字 | func(1, 2, 3) 或 func(1, 2, pos_or_kw=3) |
| 兼容兩種傳遞方式 | |||
| `*` 之後 | kw_only1, kw_only2 | 僅關鍵字參數 | 調用時**必須**寫 `kw_only1=值` |
| func(1, 2, 3, kw_only1=4, kw_only2=5) | 順序無關,名字綁定 |
# 強制位置參數:用戶只能寫 add(1, 2),不能寫 add(a=1, b=2)
def add(a, b, /):
return a + b
# 混合:前兩個位置,第三個可選關鍵字,最後只能關鍵字
def process(data, config, /, mode='fast', *, timeout=30):
print(f"data={data}, config={config}, mode={mode}, timeout={timeout}")
process("input", "cfg") # ✅ 位置參數
process("input", "cfg", "slow") # ✅ mode 位置傳遞
process("input", "cfg", mode="slow") # ✅ mode 關鍵字傳遞
process("input", "cfg", timeout=10) # ✅ timeout 必須關鍵字
# process(data="input", config="cfg") # ❌ TypeError: positional-only arguments passed as keyword
| 誤區 | 事實 |
|---|---|
| 斜線表示可變參數 `*args` | ❌ 可變位置參數是 `*args`,斜線 `/` 是分隔符,標記前面參數為位置-only |
| 所有內建函數都有 `/` | ❌ 僅位置參數優先的內建函數顯示,如 `print(*objects, sep=' ', end='\n', file=sys.stdout)` 無 `/`,因其參數設計為關鍵字友好 |
| 斜線後不能有默認值 | ❌ `/` 前的參數**可以**有默認值,如 `def f(a, b=1, /):` 合法,調用 `f(1)` 或 `f(1, 2)` 均可,但不能 `f(a=1)` |
函數簽名末尾的斜線 `/` 是 Python 3.8+ 引入的**位置-only 參數標記**,源自內建函數的 C 層實現慣例,旨在**提升解析性能、隱藏參數名實現細節、強化 API 穩定性**。自定義函數中,若追求極致性能或需模擬內建函數語義,可合理使用 `/` 配合 `*` 精確控制參數傳遞方式;日常業務代碼通常無需強制,保持參數可位置可關鍵字(`/` 之前無參數)即可。