为什么不能同时将 args 和仅关键字参数与 *args 和 **kwargs 混合
Why can't both args and keyword only arguments be mixed with *args and **kwargs simultaneously
我很清楚 python 中 *args 和 **kwargs 的用法,SO 中有很多问题(例如 Use of *args and **kwargs and What does ** (double star/asterisk) and * (star/asterisk) do for parameters?)。
但我想了解的一件事是:为什么不能同时定义强制位置参数、强制 kwarg 参数并最终仍然允许捕获其他参数和 kwarg,如下面的 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, *, b, **kwargs):
print(a, b)
for key, value in kwargs.items():
print(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, **kwargs):
print(a, b)
print(args)
for key, value in kwargs.items():
print(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, *args, **kwargs):
print(a, b)
print(args)
print(kwargs)
是的,可以删除 could_do_this_but
函数签名中的 b
,在函数顶部执行(例如)kwargs.get("b", None)
并在发现时引发一些适当的错误None
...但是在函数签名上直接使用“b”将允许更快、更明确的代码开发使用该函数。
正确的语法是def cant_do_that(a, *args, b, **kwargs):
。请注意,*
仅使用一次,both 用于标记位置参数的结尾, 和 用于设置可变位置参数的名称。
function definition is syntactically unique 中的 *
在 positional-or-keyword 和 keyword-only 参数之间的分隔处:
parameter_list_starargs ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
| "**" parameter [","]
简而言之,语法 "*" [parameter]
意味着 *
和 *args
在句法上是相同的东西——文字 *
和可选名称——可能只出现一次。使用裸 *
来启动 keyword-only 参数 而无需 接受可变位置参数,并使用命名 *args
来启动 keyword-only 参数 with 采用可变位置参数。
If the form “*identifier
” is present, it is initialized to a tuple
receiving any excess positional parameters, defaulting to the empty
tuple. [...] Parameters after “*
” or “*identifier
” are keyword-only
parameters and may only be passed used keyword arguments.
我很清楚 python 中 *args 和 **kwargs 的用法,SO 中有很多问题(例如 Use of *args and **kwargs and What does ** (double star/asterisk) and * (star/asterisk) do for parameters?)。
但我想了解的一件事是:为什么不能同时定义强制位置参数、强制 kwarg 参数并最终仍然允许捕获其他参数和 kwarg,如下面的 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, *, b, **kwargs):
print(a, b)
for key, value in kwargs.items():
print(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, **kwargs):
print(a, b)
print(args)
for key, value in kwargs.items():
print(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, *args, **kwargs):
print(a, b)
print(args)
print(kwargs)
是的,可以删除 could_do_this_but
函数签名中的 b
,在函数顶部执行(例如)kwargs.get("b", None)
并在发现时引发一些适当的错误None
...但是在函数签名上直接使用“b”将允许更快、更明确的代码开发使用该函数。
正确的语法是def cant_do_that(a, *args, b, **kwargs):
。请注意,*
仅使用一次,both 用于标记位置参数的结尾, 和 用于设置可变位置参数的名称。
function definition is syntactically unique 中的 *
在 positional-or-keyword 和 keyword-only 参数之间的分隔处:
parameter_list_starargs ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
| "**" parameter [","]
简而言之,语法 "*" [parameter]
意味着 *
和 *args
在句法上是相同的东西——文字 *
和可选名称——可能只出现一次。使用裸 *
来启动 keyword-only 参数 而无需 接受可变位置参数,并使用命名 *args
来启动 keyword-only 参数 with 采用可变位置参数。
If the form “
*identifier
” is present, it is initialized to a tuple receiving any excess positional parameters, defaulting to the empty tuple. [...] Parameters after “*
” or “*identifier
” are keyword-only parameters and may only be passed used keyword arguments.