问题描述
我很清楚在Python中使用* args和** kwargs的情况,因此在SO中有很多问题(例如Use of *args and **kwargs和What does ** (double star/asterisk) and * (star/asterisk) do for parameters?)。
但是我想了解的一件事是:为什么不可能同时定义强制性的位置args,强制性的kwarg参数,并最终仍然允许捕获其他args和kwargs,如下面的cant_do_that
一样?
def one_kwarg_is_mandatory(*,b,**kwargs):
print(b)
for key,value in kwargs.items():
print(key,value)
def one_pos_arg_and_one_kwarg_are_mandatory(a,*,**kwargs):
print(a,b)
for key,value)
# I wanted a mandatory arg (a) and possibly parse other args (*args),# then a mandatory kwarg (b) and eventually other kwargs (**kwargs)
def cant_do_that(a,*args,b)
print(args)
for key,value)
# not really interested on this because "b" must be a kwarg and hiding
# it under **kwargs would not be explicit enough for my customer (sometimes myself ;))
def Could_do_this_but(a,b)
print(args)
print(kwargs)
是的,可以摆脱b
函数签名中的Could_do_this_but
,在函数顶部执行(例如)kwargs.get("b",None)
并在发现{{ 1}} ......但是直接在函数签名上使用“ b”将允许使用该函数进行更快,更明确的代码开发。
解决方法
正确的语法是def cant_do_that(a,*args,b,**kwargs):
。请注意,*
仅使用一次,两者都用于标记位置参数的结尾,并且来设置可变位置参数的名称。
function definition is syntactically unique中的*
,位于位置或关键字参数与仅关键字参数之间:
parameter_list_starargs ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
| "**" parameter [","]
简而言之,语法"*" [parameter]
意味着*
和*args
在语法上是同一个东西–文字*
和可选名称–只能出现一次。使用裸露的*
来启动纯关键字参数而没有接受可变参数的位置参数,并使用命名为*args
来启动纯关键字参数 with 接受可变参数的位置论证。
如果存在形式“
*identifier
”,则将其初始化为元组 接收任何多余的位置参数,默认为空 元组。 [...]“*
”或“*identifier
”之后的参数仅是关键字 参数,并且只能使用关键字参数传递。