TL;DR: 关键字参数和普通关键字参数不同。
关键字参数是在函数调用时在*args
之后和**kwargs
之前的参数。例如,考虑这个通用函数的头部:
def func(arg, *args, kwonly, **kwargs):
在上面的代码中,
kwonly
接受一个关键字参数。这意味着在给它赋值时必须提供参数的名称。换句话说,你必须明确地编写:
func(..., kwonly=value, ...)
不仅传递值:
func(..., value, ...)
为了更好地解释,考虑上述函数的示例调用:
func(1, 2, kwonly=3, kw=4)
当Python解释这个调用时,它将会:
Assign arg
to 1
because its position in the function signature matches the position of 1
in the call.
Place 2
in *args
because *args
collects any extra positional arguments and 2
is extra.
Assign kwonly
to 3
because we have (as is necessary) explicitly told it to. Note that if we had done this instead:
func(1, 2, 3, kw=4)
3
would also be placed in *args
and a TypeError
would be raised for not supplying an argument to kwonly
(since we did not give it a default value in this case).
Place kw=4
in **kwargs
because it is an extra keyword argument, which are collected by **kwargs
.
以下是我之前所述的演示内容:
>>> def func(arg, *args, kwonly, **kwargs):
... print('arg:', arg)
... print('args:', args)
... print('kwonly:', kwonly)
... print('kwargs:', kwargs)
...
>>> func(1, 2, kwonly=3, kw=4)
arg: 1
args: (2,)
kwonly: 3
kwargs: {'kw': 4}
>>>
>>> func(1, 2, 3, kw=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() missing 1 required keyword-only argument: 'kwonly'
>>>
基本上,你可以将关键字参数看作必须提供参数名称才能为其赋值的关键字参数。与普通关键字参数不同,位置值是不够的。
>>> def func(kw=None):
... print('kw:', kw)
...
>>> func(kw=1)
kw: 1
>>> func(1) # Do not need the name in this case.
kw: 1
>>>
>>> def func(*, kwonly=None):
... print('kwonly:', kwonly)
...
>>> func(kwonly=1)
kwonly: 1
>>> func(1) # Always need the name with keyword-only arguments.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() takes 0 positional arguments but 1 was given
>>>
最后,我知道有些人会问“为什么需要关键字只限参数?”答案很简单,它们在某些情况下使事情更易读(特别是对于采用可变数量参数的函数)。
举个例子,考虑内置的max
函数及其关键字-only key
参数。哪种方式更易读?像这样做:
max(lambda x: -x, arg1, arg2, arg3)
让人们记住max函数的第一个参数始终是键函数,可以这样做:
max(arg1, arg2, arg3, key=lambda x: -x)
并向所有人明确表明
lambda x: -x
是您的关键函数。此外,将
key
设置为关键字参数可以使您在不需要该参数的情况下简单地省略关键函数:
max(arg1, arg2, arg3)
不要做:
max(None, arg1, arg2, arg3)
如需更多信息,请查看以下来源: