参数类型

在 Python 3.8+ 中,函数参数可以用以下语法形式定义:

1
2
def func(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
pass

涉及三类关键的分隔符:

符号 含义
/ 位置参数分界线(在此之前的参数必须通过位置传递)
* 关键字参数分界线(在此之后的参数必须通过关键字传递)
无分隔符 既可用位置,也可用关键字传参

参数类别

位置参数(Positional arguments)

最常见的参数类型。

1
2
def add(a, b):
return a + b

调用方式:

1
2
add(1, 2)     # ✅ 位置传递
add(a=1, b=2) # ✅ 关键字传递

注意:如果没有特殊声明,Python 默认允许既用位置又用关键字。

位置限定参数(Positional-only parameters)

Python 3.8 新增 / 语法,用于限制某些参数只能通过位置传入,而不能使用关键字。

1
2
def divide(a, b, /):
return a / b

调用方式:

1
2
divide(10, 2)      # ✅ OK
divide(a=10, b=2) # ❌ TypeError: divide() got some positional-only arguments

用途:

  • 避免参数名成为公共 API 的一部分(提升封装性)。
  • 对性能要求高的内建函数多采用此方式(例如 len(obj))。

例子:

1
2
3
4
5
def pow(x, y, /, z=None):
pass

# pow(2, 3, z=10) ✅
# pow(x=2, y=3) ❌

关键字限定参数(Keyword-only parameters)

使用 * 指明某些参数必须通过关键字传递

1
2
def connect(host, *, timeout, use_ssl):
print(host, timeout, use_ssl)

调用方式:

1
2
connect('localhost', timeout=10, use_ssl=True)  # ✅ OK
connect('localhost', 10, True) # ❌ TypeError

用途:

  • 提高函数调用的可读性。
  • 防止参数顺序出错。

混合使用示例

1
2
def example(a, b, /, c, d=10, *, e, f=20):
print(a, b, c, d, e, f)

✅ 合法调用方式:

1
2
example(1, 2, 3, e=4)
example(1, 2, 3, 11, e=4, f=5)

❌ 非法调用方式:

1
2
example(a=1, b=2, c=3, e=4)  # a,b 是位置限定参数
example(1, 2, 3, 11, 4, 5) # e,f 是关键字限定参数

参数定义顺序

官方推荐顺序如下(从左到右):

参数类型 示例
位置参数(可混合默认值) a, b=2
/ 分隔符 /
可位置/关键字参数 c, d=3
* 分隔符 *
关键字限定参数(含默认值) e, f=5
可变参数 *args, **kwargs

完整范例:

1
2
def func(a, b=2, /, c=3, *, d=4, **kwargs):
print(a, b, c, d, kwargs)

应用建议

场景 建议用法
封装公共 API,不希望调用者依赖参数名 使用 /
提升可读性、强制命名参数 使用 *
对内部函数(如性能函数)进行调用优化 使用 /
对用户接口(如配置函数) 使用 * 强制关键字参数

应用举例

许多内建函数都使用 /

1
2
>>> help(len)
len(obj, /)

这表示 len() 的参数 必须通过位置传递

同理:

1
2
>>> help(divmod)
divmod(x, y, /)

总结表

参数类型 定义方式 调用方式 示例
位置参数 无标记 f(1, 2) def f(a, b):
位置限定参数 / 前定义 f(1, 2) def f(a, b, /):
关键字限定参数 * 后定义 f(x=1) def f(*, x):
通用参数 /* 之间 f(1)f(x=1) def f(a, /, b, *, c):