短语"关键词只有args"在Python中有点含糊不清 - 通常我认为它是指传递给**kwarg
参数的args。但是,inspect
模块似乎区分了**kwarg
和名为"仅关键字参数"。
来自the docs:
inspect.getfullargspec(FUNC)
获取Python函数参数的名称和默认值。一个 返回名为tuple:
FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)
args
是参数名称的列表。varargs
和varkw
是名称*
和**
参数或None
。 defaults是一个n元组 最后n个参数的默认值,如果没有,则为None 默认参数。kwonlyargs
是仅关键字参数的列表 名。kwonlydefaults
是一个将kwonlyargs
的名称映射到的字典 默认值。annotations
是一个字典映射参数名称 注释
因此,检查模块有一个名为kwonlyargs
和kwonlydefaults
的东西。这在实际的功能签名中意味着什么?如果您有一个接受**kwarg
参数的函数签名,那么在运行时之前您无法真正知道关键字参数的名称,因为调用者基本上只能传递任意字典。那么,kwonlyargs
在函数签名的上下文中具有什么含义 - 这是inspect.getfullargspec
提供的内容。
答案 0 :(得分:11)
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
>>>
最后,我知道有些人在思考&#34;为什么还要使用仅限关键字的参数?&#34;答案很简单,它们在某些情况下使事情更具可读性(特别是对于采用可变数量参数的函数)。
作为示例,请考虑内置的max
函数及其仅关键字key
参数。什么更具可读性?做这样的事情:
max(lambda x: -x, arg1, arg2, arg3)
让人们记住 max
的第一个参数始终是key function或者这样做:
max(arg1, arg2, arg3, key=lambda x: -x)
并向所有人明确lambda x: -x
是您的关键功能。另外,使key
成为仅限关键字的参数,如果您不需要,只需省略键功能:
max(arg1, arg2, arg3)
而不是:
max(None, arg1, arg2, arg3)
有关详细信息,请查看以下来源: