TL;DR:仅关键字参数与普通关键字参数不同。
仅关键字参数是在函数调用中出现在 *args 之后和 **kwargs 之前的参数。例如,考虑这个通用函数头:
def func(arg, *args, kwonly, **kwargs):
在上面,kwonly 采用仅关键字参数。这意味着你必须在给它一个值时提供它的名字。换句话说,你必须明确地写:
func(..., kwonly=value, ...)
而不仅仅是传递一个值:
func(..., value, ...)
为了更好地解释,请考虑上面给出的函数的这个示例调用:
func(1, 2, kwonly=3, kw=4)
当 Python 解释这个调用时,它将:
将arg 分配给1,因为它在函数签名中的位置与调用中1 的位置相匹配。
将2 放在*args 中,因为*args 收集任何额外的位置参数,而2 是额外的。
-
将kwonly 分配给3,因为我们已经(必要时)明确告诉它这样做。请注意,如果我们改为这样做:
func(1, 2, 3, kw=4)
3 也将被放置在 *args 中,并且 TypeError 将因未向 kwonly 提供参数而引发(因为在这种情况下我们没有给它一个默认值)。
将kw=4放在**kwargs中,因为它是一个额外的关键字参数,由**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) # Should have written: 'kwonly=3'
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 函数及其关键字key 参数。什么对您来说更具可读性?做这样的事情:
max(lambda x: -x, arg1, arg2, arg3)
并让人们记住max 的第一个参数始终是key function,或者这样做:
max(arg1, arg2, arg3, key=lambda x: -x)
并向所有人明确lambda x: -x 是您的关键职能。此外,将 key 设为仅关键字参数可以让您在不需要时简单地省略 key 函数:
max(arg1, arg2, arg3)
而不是做:
max(None, arg1, arg2, arg3)
有关更多信息,您可以查看以下来源: