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

Python 增强提案

PEP 457 – 仅限位置参数的表示法

作者:
Larry Hastings <larry at hastings.org>
讨论至:
Python-Dev 列表
状态:
最终版
类型:
信息性
创建日期:
2013年10月8日

目录

概述

本 PEP 提出了 Python 中仅限位置参数的表示法。仅限位置参数是没有外部可用名称的参数;当调用接受仅限位置参数的函数时,位置参数仅根据其位置映射到这些参数。

本 PEP 是一个信息性 PEP,描述了在描述使用仅限位置参数的 API(例如在 Argument Clinic 中,或在 inspect.Signature 对象的字符串表示中)时使用的表示法。另一个 PEP,PEP 570,提议将此表示法提升为完整的 Python 语法。

基本原理

Python 始终支持仅限位置参数。Python 的早期版本缺乏按名称指定参数的概念,所以自然所有参数都是仅限位置的。这种情况在大约 Python 1.0 左右发生了变化,当时所有参数突然变成了位置或关键字参数。但是,即使在当前版本的 Python 中,许多 CPython 的“内置”函数仍然只接受仅限位置参数。

用现代 Python 实现的函数可以通过可变参数 *args 参数接受任意数量的仅限位置参数。但是,没有 Python 语法来指定接受特定数量的仅限位置参数。换句话说,有许多内置函数的签名无法用 Python 语法表示。

本 PEP 提出了一种用于此类签名的表示法,它可以构成向后兼容语法的基础,该语法应该允许在纯 Python 代码中实现任何内置函数(有关该提案,请参阅PEP 570)。

当前 Python 中仅限位置参数的语义

有许多内置函数只接受仅限位置参数。由此产生的语义对于 Python 程序员来说很容易体验到——只需尝试调用其中一个,并通过名称指定其参数即可。

>>> pow(x=5, y=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pow() takes no keyword arguments

此外,还有一些函数具有特别有趣的语义。

  • range(),它接受一个在其所需参数*左侧*的可选参数。[2]
  • dict(),其映射/迭代器参数是可选的,并且在语义上必须是仅限位置的。此参数的任何外部可见名称都会遮蔽该名称进入 **kwarg 关键字可变参数字典![1]

显然,可以通过接受 (*args, **kwargs) 并手动解析参数,在纯 Python 代码中模拟其中任何一个。但这会导致 Python 函数的签名与其实际接受的参数之间出现脱节,更不用说实现所述参数解析的工作了。

动机

本 PEP 不建议我们在 Python 中实现仅限位置参数。本 PEP 的目标只是定义语法,以便

  • 文档可以清晰、明确、一致地表达函数的参数将如何解释。
  • 该语法保留供将来使用,以防社区某天决定将仅限位置参数添加到语言中。
  • Argument Clinic 可以使用该语法的一种变体作为其输入的一部分,用于定义内置函数的参数。

仅限位置参数文档的现状

仅限位置参数的文档不完整且不一致。

  • 有些函数通过将可选的仅限位置参数*组*括在嵌套的方括号中来表示。[3]
  • 有些函数通过呈现具有不同参数数量的多个原型来表示可选的仅限位置参数组。[4]
  • 有些函数使用上述两种方法。[2] [5]

还有一个重要的想法需要考虑:目前在文档中无法判断函数是否接受仅限位置参数。open() 接受关键字参数,ord() 不接受,但仅仅通过阅读文档无法判断这是真的。

语法和语义

从“万米高空”来看,暂时忽略 *args**kwargs,函数定义的语法目前看起来像这样。

def name(positional_or_keyword_parameters, *, keyword_only_parameters):

基于这种观点,函数的新语法将如下所示。

def name(positional_only_parameters, /, positional_or_keyword_parameters,
         *, keyword_only_parameters):

/ 之前的所有参数都是仅限位置的。如果函数签名中未指定 /,则该函数不接受任何仅限位置参数。

仅限位置参数可以有默认值,如果有默认值,则它们是可选的。没有默认值的仅限位置参数是“必需”的仅限位置参数。

仅限位置参数的更多语义

  • 尽管仅限位置参数在技术上具有名称,但这些名称仅供内部使用;仅限位置参数*绝不能*通过名称进行外部寻址。(类似于 *args**kwargs。)
  • 如果 / 之后有参数,则必须在 / 之后指定一个逗号,就像在表示转换为仅限关键字参数的 * 之后有一个逗号一样。
  • 此语法对 *args**kwargs 没有影响。

其他限制

Argument Clinic 使用这种语法的一种形式来指定内置函数。它施加了理论上不必要但使实现更容易的进一步限制。具体来说:

  • 具有仅限位置参数的函数目前不能具有任何其他类型的参数。(这在不久的将来可能会稍微放宽。)
  • Argument Clinic 支持一种称为“可选组”的附加语法。“可选组”是一组顺序的仅限位置参数,它们必须作为一个组被指定或不被指定。例如,如果在 Argument Clinic 中定义了一个接受四个参数的函数,并且所有参数都是仅限位置的并且属于一个可选组,那么在调用函数时必须指定零个参数或四个参数。这对于覆盖更多的 Python 遗留库是必要的,但超出了本 PEP 的范围,不建议实际包含在 Python 语言中。

未来实现者的注意事项

如果我们决定在未来版本的 Python 中实现仅限位置参数,我们将不得不做一些额外的工作来保留它们的语义。问题是:当函数被调用时,我们如何通知参数没有为其传递任何值?

显而易见的解决方案是:向 Python 添加一个新的单例常量,当参数未映射到参数时传递该常量。我建议将该值命名为 undefined,并将其作为名为 Undefined 的特殊类的单例。如果仅限位置参数在调用时未接收到参数,则其值将设置为 undefined

但这又引出了一个问题。我们如何区分“此仅限位置参数未接收到参数”和“调用者为此参数传入了 undefined”?

禁止将 undefined 作为参数传递给函数(例如,引发异常)会很好。但这会降低 Python 的速度,而且“同意的成年人”规则在这里似乎适用。因此,禁止它可能应该受到强烈劝阻,但不应完全阻止。

但是,应该允许(并鼓励)用户函数将 undefined 指定为参数的默认值。

未解决的问题

Python 中有三种类型的参数:

  1. 仅限位置参数,
  2. 位置或关键字参数,以及
  3. 仅限关键字参数。

Python 允许函数同时具有 2 和 3。而一些内置函数(例如 range)同时具有 1 和 3。那么同时具有 1 和 2 的函数有意义吗?或者以上所有类型?

致谢

将“/”用作仅限位置参数和位置或关键字参数之间分隔符的功劳归于 Guido van Rossum,这是他 2012 年的一项提案。[6]

将左侧选项组赋予更高优先级的功劳归于 Alyssa Coghlan。(2013 年在美国 PyCon 上的面对面交流。)


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

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