Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 3102 – 仅限关键字的参数

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

目录

摘要

本PEP提议改变函数参数分配给命名参数槽的方式。特别是,它允许声明“仅限关键字”参数:只能通过关键字提供且永远不会被位置参数自动填充的参数。

基本原理

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

通常情况下,函数需要接受可变数量的参数。Python语言通过“可变参数”语法(*name)支持这一点,该语法指定将任何“剩余”参数作为元组传递给可变参数。

对此的一个限制是,目前,所有常规参数槽都必须在可变参数槽之前填充。

这并非总是可取的。人们可以轻易想象一个函数,它接受可变数量的参数,但也接受一个或多个以关键字参数形式出现的“选项”。目前,唯一的方法是同时定义一个可变参数(varargs)和一个“关键字”参数(**kwargs),然后手动从字典中提取所需的关键字。

规范

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

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

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

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

第二个语法更改是允许省略可变参数的参数名称。其含义是允许那些不接受可变参数的函数使用仅限关键字的参数。

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

这项更改背后的原因如下。假设一个函数接受几个位置参数以及一个关键字参数。

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

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

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已宣布支持这种“单星”语法来表示位置参数的结束。)

函数调用行为

上一节描述了旧行为和新行为之间的区别。然而,拥有一个独立于旧模型的新行为描述也很有用。因此,下一节将尝试提供这样的描述。

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

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

根据当前的 Python 实现,遇到的任何错误都将通过引发 TypeError 来表示。(如果您想要不同的行为,那是另一个 PEP 的主题。)

向后兼容性

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


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

最后修改:2025-02-01 08:59:27 GMT