Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 增强提案

PEP 3102 – 仅限关键字参数

作者:
Talin <viridia at gmail.com>
状态:
最终
类型:
标准跟踪
创建:
2006 年 4 月 22 日
Python 版本:
3.0
历史记录:
2006 年 4 月 28 日,2006 年 5 月 19 日

目录

摘要

本 PEP 提出更改函数参数分配给命名参数槽的方式。特别是,它使声明“仅限关键字”参数成为可能:这些参数只能通过关键字提供,并且永远不会被位置参数自动填充。

基本原理

当前的 Python 函数调用范式允许通过位置或关键字指定参数。参数可以通过名称显式填充,也可以通过位置隐式填充。

在许多情况下,函数需要接受可变数量的参数。Python 语言使用“varargs”语法 (*name) 支持这一点,该语法指定任何“剩余”参数都将作为元组传递到 varargs 参数中。

当前,这方面的局限性在于,所有常规参数槽都必须先填充,才能填充 vararg 槽。

这并不总是可取的。可以轻松地想象一个接受可变数量的参数,但也接受一个或多个“选项”作为关键字参数的函数。当前,唯一的方法是定义一个 varargs 参数和一个“keywords”参数 (**kwargs),然后手动从字典中提取所需的关键字。

规范

从语法上来说,拟议的更改相当简单。第一个更改是允许常规参数出现在 varargs 参数之后。

def sortwords(*wordlist, case_sensitive=False):
    ...

此函数接受任意数量的位置参数,以及一个名为“case_sensitive”的关键字选项。该选项永远不会被位置参数填充,但必须通过名称显式指定。

仅限关键字参数不需要具有默认值。由于 Python 要求所有参数都绑定到值,并且由于绑定到仅限关键字参数的值的唯一方式是通过关键字,因此这些参数是“必需关键字”参数。这些参数必须由调用方提供,并且必须通过关键字提供。

第二个语法更改是允许省略 varargs 参数的 Argument name。这意味着允许为那些本来不接受 varargs 参数的函数提供仅限关键字参数。

def compare(a, b, *, key=None):
    ...

此更改背后的原因如下。想象一下一个接受多个位置参数以及一个关键字参数的函数。

def compare(a, b, key=None):
    ...

现在,假设您想让“key”成为仅限关键字的参数。在上述语法下,您可以通过在关键字参数之前添加 varargs 参数来实现这一点。

def compare(a, b, *ignore, key=None):
    ...

不幸的是,“ignore”参数还会吸收调用方可能提供的任何错误的位置参数。鉴于我们希望任何不需要的参数都引发错误,我们可以这样做。

def compare(a, b, *ignore, key=None):
    if ignore:  # If ignore is not empty
        raise TypeError

作为一个方便的快捷方式,我们可以简单地省略“ignore”名称,这意味着“不允许任何位置参数超出此点”。

(注意:在对替代语法提案进行大量讨论之后,BDFL 已表示支持此“单星”语法来指示位置参数的结束。)

函数调用行为

上一节描述了旧行为和新行为之间的差异。但是,拥有一个独立描述新行为也很有用,而无需参考以前的模型。因此,下一节将尝试提供这样的描述。

调用函数时,输入参数按如下方式分配给形式参数

  • 对于每个形式参数,都有一个槽用于保存分配给该参数的 Argument value。
  • 已分配值的槽标记为“已填充”。尚未分配值的槽被视为“空”。
  • 最初,所有槽都标记为“空”。
  • 位置参数首先分配,然后是关键字参数。
  • 对于每个位置参数
    • 尝试将 Argument 绑定到第一个未填充的参数槽。如果该槽不是 vararg 槽,则将其标记为“已填充”。
    • 如果下一个未填充的槽是 vararg 槽,并且它没有名称,则这是一个错误。
    • 否则,如果下一个未填充的槽是 vararg 槽,则所有剩余的非关键字 Argument 都将放入 vararg 槽中。
  • 对于每个关键字参数
    • 如果存在与关键字名称相同的参数,则 Argument value 将分配给该参数槽。但是,如果参数槽已填充,则这是一个错误。
    • 否则,如果存在“关键字字典”参数,则使用关键字名称作为字典键将 Argument 添加到字典中,除非已经存在具有该键的条目,在这种情况下这是一个错误。
    • 否则,如果没有关键字字典,也没有匹配的命名参数,则这是一个错误。
  • 最后
    • 如果 vararg 槽尚未填充,则将空元组分配为其值。
    • 对于每个剩余的空槽:如果该槽具有默认值,则用默认值填充该槽。如果没有默认值,则这是一个错误。

根据当前的 Python 实现,遇到的任何错误都将通过引发 TypeError 来发出信号。(如果您想要其他东西,那就是另一个 PEP 的主题。)

向后兼容性

本 PEP 中指定的函数调用行为是现有行为的超集 - 也就是说,预期任何现有程序都将继续工作。


来源:https://github.com/python/peps/blob/main/peps/pep-3102.rst

最后修改时间:2023 年 9 月 9 日 17:39:29 GMT