Python检查模块:仅限关键字args

时间:2014-11-16 23:27:31

标签: python function python-3.x arguments signature

短语"关键词只有args"在Python中有点含糊不清 - 通常我认为它是指传递给**kwarg参数的args。但是,inspect模块似乎区分了**kwarg和名为"仅关键字参数"。

来自the docs

  

inspect.getfullargspec(FUNC)

     

获取Python函数参数的名称和默认值。一个   返回名为tuple:

     

FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)

     

args是参数名称的列表。 varargsvarkw是名称   ***参数或None。 defaults是一个n元组   最后n个参数的默认值,如果没有,则为None   默认参数。 kwonlyargs是仅关键字参数的列表   名。 kwonlydefaults是一个将kwonlyargs的名称映射到的字典   默认值。 annotations是一个字典映射参数名称   注释

因此,检查模块有一个名为kwonlyargskwonlydefaults的东西。这在实际的功能签名中意味着什么?如果您有一个接受**kwarg参数的函数签名,那么在运行时之前您无法真正知道关键字参数的名称,因为调用者基本上只能传递任意字典。那么,kwonlyargs函数签名的上下文中具有什么含义 - 这是inspect.getfullargspec提供的内容。

1 个答案:

答案 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)

有关详细信息,请查看以下来源: