Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

函数参数中的 * 是什么意思?

一句话先给结论

在函数参数中:

* 的作用是:强制后面的参数只能用「关键字参数」方式传入


一、最直观的对比示例

❌ 没有 *

def f(a, b, c):
    print(a, b, c)

f(1, 2, 3)      # ✅
f(1, b=2, c=3)  # ✅

✅ 有 *

def f(a, *, b, c):
    print(a, b, c)

f(1, b=2, c=3)   # ✅
f(1, 2, 3)       # ❌ TypeError

📌 bc 只能用关键字传参


二、扩展示例

def resolve_path(
    path: str,
    *,
    parents: int = 0,
    **kwargs,
) -> str | None:

这意味着:

  • path位置参数
  • parents必须显式写名字
  • kwargs → 额外关键字参数

正确调用方式

resolve_path("a/b/c.txt", parents=1)

错误调用方式

resolve_path("a/b/c.txt", 1)   # ❌ 不允许

📌 这是刻意设计的 API 约束


三、为什么工程里「强烈推荐」使用 *

1️⃣ 防止参数位置混淆(尤其是布尔 / 数字)

对比一下:

sendemail(smtp, sender, recipients, subject, body, True)

vs

sendemail(
    smtp,
    sender,
    recipients,
    subject,
    body,
    images=None,
)

💡 第二种一眼就知道每个参数是干嘛的


2️⃣ 防止未来改接口时“炸用户代码”

没有 * 的灾难场景:

def func(a, b):
    ...

加了参数:

def func(a, b, c=0):
    ...

用户代码:

func(1, 2)      # OK
func(1, 2, 3)   # 😬 意外改变语义

使用 *

def func(a, *, b=0):
    ...

👉 API 稳定性直接拉满


四、* 的三种常见用法(非常重要)

① 强制关键字参数

def f(a, *, b, c):
    ...

② 分隔位置参数与 *args

def f(a, *args):
    ...

这里的 *args 是:

args == tuple(...)

③ 函数签名中的「只读分隔符」(高级)

def f(a, b, /, c, *, d):
    ...

含义:

  • a, b:只能位置传参
  • c:位置 or 关键字
  • d:只能关键字

📌 这是 Python 3.8+ 的完整参数控制模型


五、工程级「参数设计黄金法则」

能加 * 就加 *

特别适合:

  • 工具函数
  • 公共库
  • SDK
  • 会长期维护的接口

推荐模板

def func(
    required: str,
    *,
    option: int = 0,
    flag: bool = False,
) -> None:
    ...

六、用一句话记住

* 不是语法糖
它是 Python 提供的 API 设计武器