Python函数参数中单独的*有何作用?与*args有什么区别?
Python函数参数列表中单独
*符号的作用说明 你给出的示例代码如下:
class Field: def __init__(self, *, read_only=False, write_only=False): do_something()
核心作用
参数列表中不绑定变量名的单独*是Python 3支持的语法,作用是标记仅限关键字参数分隔符:*之后定义的所有参数,调用时必须显式通过关键字(即参数名=值的形式)传递,绝对不能按位置顺序传参。
以上述Field类的构造方法为例,Field(True, False)这种按位置传参的写法会直接抛出TypeError,只有写成Field(read_only=True, write_only=False)的形式才能正常调用。
常见使用场景
- 规避位置传参的顺序错误:对于布尔值、同类型枚举值这类语义辨识度低、容易记混顺序的参数,强制关键字传参要求调用时必须写出参数名,从根源避免传反参数导致的逻辑bug,这类bug通常隐蔽性强、排查成本高。
- 提升API的可维护性:如果是对外提供的公共接口,后续迭代新增参数时,只要把新参数放在
*之后,就不会破坏原有按位置传参的旧调用逻辑,不会因为参数列表变长导致旧代码的传参位置错位。 - 提升代码可读性:调用处显式写出参数名,不需要跳转到函数定义核对参数顺序,就能直接看懂每个传值的含义。
和*args写法的差异
两者虽然都能让后续参数变成仅限关键字参数,但核心逻辑完全不同:
- 对多余位置参数的处理不同
单独*只是一个语法标记,不会接收、存储任何传入的位置参数,如果调用时传入了没有对应位置形参的位置参数,会直接抛出类型错误。*args会把所有匹配不到固定位置形参的多余位置参数打包成元组,绑定到args变量上供函数内部逻辑使用,允许传入任意数量的额外位置参数。 - 适用场景不同
单独*适用于不需要接收可变长度位置参数,仅需要强制后续参数走关键字传参的场景。*args适用于本身就需要支持可变数量位置参数的场景,后续参数自动成为仅限关键字参数只是附带效果。
举个直观的对比例子:
# 用单独*的写法 def demo1(*, a=1): print(a) # demo1(2) # 报错,不接受位置传参 demo1(a=2) # 正常运行 # 用*args的写法 def demo2(*args, a=1): print(f"多余位置参数:{args}, a的值:{a}") demo2(1,2,3, a=4) # 正常运行,输出:多余位置参数:(1, 2, 3), a的值:4
内容的提问来源于stack exchange,提问作者Msv
相关产品推荐
相关产品推荐

