当前位置: 首页 > 知识库问答 >
问题:

Python检查模块:仅关键字参数

弓胜泫
2023-03-14

Python中的短语“仅关键字args”有点含糊——通常我认为它是指传递给< code>**kwarg参数的args。然而,< code>inspect模块似乎对< code>**kwarg和所谓的“仅关键字参数”进行了区分。

来自文档:

inspect.getfullargspec(func)

获取Python函数参数的名称和默认值。返回一个命名元组:

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

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

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

共有1个答案

苏嘉志
2023-03-14

TL;DR:只有关键字的参数不同于普通的关键字参数。

仅关键字参数是函数调用中位于*args之后和*kwargs之前的参数。例如,考虑这个通用函数头:

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

在上面的代码中,< code>kwonly只接受一个关键字参数。这意味着在给它赋值时,必须提供它的名称。换句话说,您必须显式地编写:

func(..., kwonly=value, ...)

而不仅仅是传递一个值:

func(..., value, ...)

为了更好地解释,考虑上面给出的函数调用示例:

func(1, 2, kwonly=3, kw=4)

当Python解释这个调用时,它会:

>

  • arg 分配给 1,因为它在函数签名中的位置与调用中 1 的位置匹配

    将< code>2放在< code>*args中,因为< code>*args收集任何额外的位置参数,而< code>2是多余的。

    kwonly 分配给 3,因为我们(必要时)明确告诉它。请注意,如果我们这样做了:

    func(1, 2, 3, kw=4)
    

    < code>3也将放在< code>*args中,并且由于没有向< code>kwonly提供参数,将引发一个< code>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 函数及其仅关键字键参数。什么对你来说更具可读性?做这样的事情:

    max(lambda x: -x, arg1, arg2, arg3)
    

    让人们记住max的第一个参数始终是关键函数,或者这样做:

    max(arg1, arg2, arg3, key=lambda x: -x)
    

    让每个人都明白< code>lambda x: -x是你的关键函数。此外,使< code>key成为一个仅包含关键字的参数允许您在不需要时简单地省略key函数:

    max(arg1, arg2, arg3)
    

    而不是做:

    max(None, arg1, arg2, arg3)
    

    有关更多信息,您可以查看以下来源:

      < Li > https://docs . python . org/3/reference/compound _ stmts . html # function < Li > https://docs . python . org/3/reference/expressions . html # calls < Li > https://docs . python . org/3/glossary . html # term-parameter

  •  类似资料:
    • 目前为止,我们使用函数时所用的参数都是位置参数,即传入函数的实际参数必须与形式参数的数量和位置对应。而本节将介绍的关键字参数,则可以避免牢记参数位置的麻烦,令函数的调用和参数传递更加灵活方便。 关键字参数 是指使用形式参数的名字来确定输入的参数值。通过此方式指定函数实参时,不再需要与形参的位置完全一致,只要将参数名写正确即可。 因此,Python 函数的参数名应该具有更好的语义,这样程序可以立刻明

    • 问题内容: “关键字参数”与常规参数有何不同?不能将所有参数都传递为而不是使用位置语法吗? 问题答案: 有两个相关的概念,都称为“ 关键字参数 ”。 在调用方(这是其他评论者提到的),您可以通过名称指定一些函数自变量。您必须在所有不带名称的参数(位置参数)之后提及它们,并且对于所有未提及的参数都必须有默认值。 另一个概念是在函数定义方面:您可以定义一个按名称接受参数的函数-甚至不必指定这些名称是什

    • 问题内容: 因此,我正在使用的API的Web POST请求中预期的可选参数实际上也是python中的保留字。因此,如何在方法调用中命名参数: 由于“ from”是关键字,因此由于语法错误而失败。如何以不遇到语法错误的方式传递此密码? 问题答案: 将其作为命令传递。

    • 问题内容: python有能力创建动态关键字吗? 例如: 我希望能够根据所选货币更改 usd 部分。 问题答案: 是的,它确实。使用在函数定义。 例: 但是你为什么需要那个呢?

    • 我使用安装了Python模块和: 如何从命令行检查它们的版本?

    • 关键字参数 Stylus支持关键字参数,或"kwargs". 允许你根据相关参数名引用参数。 下面这些例子功能上都是一样的。但是,我们可以在列表中的任何地方放置关键字参数。其余不键入参数将适用于尚未得到满足的参数。 body { color: rgba(255, 200, 100, 0.5); color: rgba(red: 255, green: 200, blue: 100, alp