最直接的方式是使用强制关键字参数,后所有参数必须以关键字形式传入且顺序无关;如def calc(*, a, b, op)只接受calc(a=1,b=2,op='add')等任意顺序的关键字调用。

让函数的参数顺序可以随意,最直接的方式是**全部使用关键字参数(keyword-only arguments)**,并配合 * 占位符强制约束调用方式。
用 * 定义纯关键字参数
在函数定义中,把 * 放在参数列表中间或开头,它之后的所有参数都变成关键字参数——调用时必须显式写参数名,且顺序无关。
-
错误写法(位置参数混用):
calc(10, 2, 'add')—— 若已加*,会报错TypeError: calc() takes 0 positional arguments but 3 were given -
正确写法(全关键字、顺序自由):
calc(op='add', a=10, b=2)或calc(b=2, op='add', a=10)都合法
完整示例:定义与调用
以下函数只接受关键字参数,且无位置参数干扰:
def calc(*, a, b, op):
if op == 'add':
return a + b
elif op == 'mul':
return a * b
else:
raise ValueError("op must be 'add' or 'mul'")
调用时任意顺序均可:
calc(a=5, b=3, op='mul')calc(op='add', b=-1, a=100)calc(b=0, a=42, op='add')
进阶:混合使用(带默认值的关键字参数)
你还可以在 * 后添加带默认值的参数,它们也属于关键字参数,调用时可省略:
def send_email(*, to, subject, body, cc=None, priority='normal'):
print(f"To: {to}, Subject: {subject}, Priority: {priority}")
调用示例:
-
send_email(to='a@b.com', subject='Hi', body='Hello')——cc和priority使用默认值 -
send_email(body='Urgent!', priority='high', to='x@y.com', subject='Alert')—— 顺序完全打乱,依然有效
为什么不用 **kwargs?
**kwargs 虽然允许任意关键字传入,但会失去参数校验和明确接口:
- 无法保证
a、b、op一定存在 - IDE 和类型检查工具(如 mypy)无法推断参数要求
- 函数签名不清晰,调用者需查源码才能知道要传什么
而 * + 明确参数名的方式,既保灵活性,又保健壮性和可读性。










