Python inspect模块:仅限关键字参数

2024-10-01 15:30:50 发布

您现在位置:Python中文网/ 问答频道 /正文

Python中的短语“keyword only args”有点含糊不清——通常我把它理解为传递给**kwarg参数的参数。然而,inspect模块似乎在**kwarg和所谓的“仅关键字参数”之间作了区分。在

来自the docs

inspect.getfullargspec(func)

Get the names and default values of a Python function’s arguments. A named tuple is returned:

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

args is a list of the argument names. varargs and varkw are the names of the * and ** arguments or None. defaults is an n-tuple of the default values of the last n arguments, or None if there are no default arguments. kwonlyargs is a list of keyword-only argument names. kwonlydefaults is a dictionary mapping names from kwonlyargs to defaults. annotations is a dictionary mapping argument names to annotations.

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


Tags: andofthedefault参数namesisargs
1条回答
网友
1楼 · 发布于 2024-10-01 15:30:50

TL;DR:纯关键字参数与普通关键字参数不同。在


仅关键字参数是函数调用中*args之后和**kwargs之前的参数。作为一个示例,考虑以下通用函数头:

def func(arg, *args, kwonly, **kwargs):

在上面,kwonly接受一个仅限关键字的参数。这意味着您必须在给它一个值时提供它的名称。换句话说,您必须明确地写下:

^{pr2}$

不只是传递一个值:

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中,并且由于没有为kwonly提供参数而引发TypeError(因为在本例中我们没有给它一个默认值)。

  • 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成为一个仅限关键字的参数,允许您在不需要键函数的情况下简单地省略它:

max(arg1, arg2, arg3)

而不是:

max(None, arg1, arg2, arg3)

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

相关问题 更多 >

    热门问题