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

Python 增强提案

PEP 645 – 允许将可选类型写成 x?

作者:
Maggie Moss <maggiebmoss at gmail.com>
发起人:
Guido van Rossum <guido at python.org>
状态:
已撤回
类型:
标准跟踪
创建日期:
2020-08-25
决议:
Typing-SIG 消息

目录

摘要

本 PEP 提议为类型添加一个 ? 运算符,允许使用 x? 来代替 Optional[x]

PEP 撤回

PEP 604 引入的 T|None 表示法,用于书写 Optional[T],是 T? 的一个很好的替代方案,并且不需要新的语法。

T? 用作 T|None 的含义,与 TypeScript 中的用法不一致,TypeScript 中的 T? 大致表示 NotRequired[T]。这种不一致很可能会让从 TypeScript 转到 Python 的开发者感到困惑。

以上代表了 typing-sig 和本 PEP 发起人的共识。

动机

类型已成为 Python 语言中一个有价值且强大的组成部分。然而,许多类型注解冗长,给使用类型注解带来了相当大的阻力。通过改进类型语法,为 Python 代码添加类型会变得更简单,并能提升 Python 用户的开发体验。

同样,一项引入 联合类型 简写语法的 PEP 已被批准并实现。

基本原理

Python 中的类型可能非常冗长,这在努力实现类型采纳时可能成为障碍。使类型更符合人体工程学,正如在 PEP 604 中对联合类型所做的那样(例如,`int | str`),将减少为新旧 Python 代码添加类型所需的精力。`Optional` 注解在部分和完全类型的 Python 代码库中都经常使用。在对 5 个类型良好的开源项目进行的小样本抽样中,平均有 7% 的注解 包含至少一个可选类型。这表明更新语法有潜力使类型更简洁,减少代码长度并提高可读性。

在类型社区中,已经 之前讨论过 简化可选类型的语法。这些讨论中的共识是 `?` 是首选运算符。Python 语法本身不支持一元 `?`,因此需要将其添加到运行时。

PEP 505 中曾提出将 `?` 符号添加到 Python 语法中,该 PEP 目前处于推迟状态。 PEP 505 提出了一系列

  • “None 合并”二元运算符 ??
  • “None 感知”属性访问运算符 ?. (“maybe dot”)
  • “None 感知”索引运算符 ?[] (“maybe subscript”)

如果 PEP 505 未来被批准,它不会干扰本 PEP 中提出的特定于类型的 `?`。同样,由于 `?` 的所有用法在概念上都是相关的,因此在学习 Python 或进行快速视觉理解方面不会造成混淆或障碍。

提议的语法,带有后缀运算符,模仿了 C#、TypeScript 和 Swift 等其他类型化语言中存在的可选语法。这些语言的广泛采用和流行意味着 Python 开发者可能已经熟悉这种语法。

// Optional in Swift
var example: String?

// Optional in C#
string? example;

添加此语法还将遵循使用内置类型作为注解的常用模式。例如,listdictNone。这将允许在 Python 代码中添加更多注解,而无需从 typing 导入。

规范

新的可选语法应被接受用于函数、变量、属性和参数注解。

# instead of
# def foo(x: Optional[int], y: Optional[str], z: Optional[list[int]): ...
def foo(x: int?, y: str?, x: list[int]?): ...

# def bar(x: list[typing.Optional[int]]): ...
def bar(x: list[int?]): ...

新的可选语法应等同于现有的 `typing.Optional` 语法。

typing.Optional[int] == int?

新的可选语法应与现有的 `typing.Optional` 语法具有相同的身份。

typing.Optional[int] is int?

它也应该等同于与 `None` 的联合。

# old syntax
int? == typing.Union[int, None]

# new syntax
int? == int | None

由于 PEP 604 中指定的新的联合语法在 isinstanceissubclass 中得到支持,因此新的可选语法应该在 isinstanceissubclass 中都得到支持。

isinstance(1, int?) # true
issubclass(Child, Super?) # true

需要实现一个新的 dunder 方法来允许对 `?` 运算符进行重载以实现其他功能。

向后兼容性

`?` 目前在 Python 语法中未使用,因此本 PEP 完全向后兼容。

参考实现

参考实现可以在 此处找到。

被拒绝的想法

讨论过的替代方案包括

  • 曾考虑使用 `~` 运算符代替 `?`。
  • 一个前缀运算符(?int)。

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

最后修改:2025-02-01 08:55:40 GMT