Python中结合特殊参数使用*args和**kwargs的方法探究
Python函数中结合
/、*与*args的正确定义方式 首先明确三个核心规则:
/左侧参数仅限位置传递,右侧参数默认支持位置或关键字传递(除非被*限制);*右侧参数仅限关键字传递,必须用关键字指定;*args用于收集未被显式定义的额外位置参数,它的位置直接决定参数传递的有效性,不能随意放置。
错误案例分析
1. function_args_s2 语法错误
def function_args_s2(p1, p2, *args, /, pk1, pk2, *, k1, k2): pass
*args 不能放在 / 之前——/ 是位置参数的终止标记,左侧只能是固定的位置参数,不能包含可变位置参数 *args,因此触发语法错误。
2. function_args_s3 参数传递受限
def function_args_s3(p1, p2, /, pk1, pk2, *args, k1, k2): pass
当 *args 放在 pk1、pk2 之后时,这两个参数会被强制为仅位置传递:因为 *args 会收集所有后续位置参数,若尝试用关键字传递 pk1/pk2,后续的位置参数无法被正确收集(Python不允许位置参数出现在关键字参数之后),导致只能通过位置方式传入这两个参数。
正确定义方式
根据需求不同,有三种常见的正确写法:
场景1:固定位置参数 + 可变位置参数 + 仅限关键字参数
保留 / 限定的位置参数,同时收集额外位置参数,最后用仅限关键字参数收尾:
def function_args_correct1(p1, p2, /, *args, k1, k2): print(f"p1={p1}, p2={p2}, args={args}, k1={k1}, k2={k2}") # 调用示例 function_args_correct1(1, 2, 3, 4, 5, k1=6, k2=7) # 输出: p1=1, p2=2, args=(3, 4, 5), k1=6, k2=7
p1、p2必须用位置传递;- 额外位置参数会被
*args收集为元组; k1、k2必须用关键字传递。
场景2:固定位置参数 + 可位置/关键字参数 + 可变位置参数 + 仅限关键字参数
让中间参数支持两种传递方式,同时保留可变位置参数收集能力:
def function_args_correct2(p1, p2, /, pk1, pk2, *args, k1, k2): print(f"p1={p1}, p2={p2}, pk1={pk1}, pk2={pk2}, args={args}, k1={k1}, k2={k2}") # 调用示例1:位置传递pk1、pk2 function_args_correct2(1, 2, 3, 4, 5, 6, k1=7, k2=8) # 输出: p1=1, p2=2, pk1=3, pk2=4, args=(5, 6), k1=7, k2=8 # 调用示例2:关键字传递pk1、pk2(此时无法再传额外位置参数) function_args_correct2(1, 2, pk1=3, pk2=4, k1=7, k2=8) # 输出: p1=1, p2=2, pk1=3, pk2=4, args=(), k1=7, k2=8
这种写法下,pk1、pk2 支持两种传递方式,但用关键字传递时,无法再传入额外位置参数给 *args。
场景3:结合**kwargs收集额外关键字参数
同时收集额外位置参数和关键字参数:
def function_args_correct3(p1, p2, /, *args, k1, k2, **kwargs): print(f"p1={p1}, p2={p2}, args={args}, k1={k1}, k2={k2}, kwargs={kwargs}") # 调用示例 function_args_correct3(1, 2, 3, 4, k1=5, k2=6, k3=7, k4=8) # 输出: p1=1, p2=2, args=(3, 4), k1=5, k2=6, kwargs={'k3':7, 'k4':8}
核心总结
*args必须放在/之后、*之前(如果有*);- 若
*args出现在普通参数之后,该参数仍支持位置/关键字传递,但用关键字传递后无法再传入额外位置参数; /和*的优先级高于*args:/左侧不能有*args,*右侧不能有*args(仅可放关键字参数和**kwargs)。
内容的提问来源于stack exchange,提问作者rabbit
相关产品推荐
相关产品推荐

