PEP 645 – 允许将可选类型写成 x?
- 作者:
- Maggie Moss <maggiebmoss at gmail.com>
- 赞助商:
- Guido van Rossum <guido at python.org>
- 状态:
- 已撤回
- 类型:
- 标准跟踪
- 创建:
- 2020-08-25
- 决议:
- Typing-SIG 消息
摘要
此 PEP 提案为类型添加一个 ?
运算符,允许将 int?
写成 Optional[int]
。
PEP 撤回
由 PEP 604 引入的记号 T|None
可以很好地替代 T?
,并且不需要新的语法。
使用 T?
代表 T|None
也与 TypeScript 不一致,在 TypeScript 中,它大致代表 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 提案了一个
- “空值合并”二元运算符
??
- “空值感知属性访问”运算符
?.
(“可能点”)- “空值感知索引”运算符
?[]
(“可能下标”)
如果将来 PEP 505 获得批准,它不会干扰此 PEP 中提出的特定于类型的 ?
。同样,由于 ?
的所有使用在概念上都是相关的,因此在学习 Python 或快速视觉理解方面不会令人困惑或构成障碍。
提出的语法,使用后缀运算符,模仿了其他类型化语言(如 C#、TypeScript 和 Swift)中找到的可选语法。这些语言的广泛采用和流行意味着 Python 开发人员可能已经熟悉这种语法。
// Optional in Swift
var example: String?
// Optional in C#
string? example;
添加此语法还将遵循使用内置类型作为注释的常用模式。例如,list
、dict
和 None
。这将允许在不从 typing
中导入的情况下,为 Python 代码添加更多注释。
规范
新的可选语法应适用于函数、变量、属性和参数注释。
# 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 中指定的新的联合语法在 isinstance
和 issubclass
中得到支持,因此新的可选语法应在 isinstance
和 issubclass
中都得到支持。
isinstance(1, int?) # true
issubclass(Child, Super?) # true
需要实现一个新的 dunder 方法,以允许 ?
运算符被重载以实现其他功能。
向后兼容性
?
当前在 Python 语法中未被使用,因此此 PEP 与向后兼容。
参考实现
可以在 此处 找到参考实现。
被拒绝的想法
讨论过的替代方案是
- 考虑使用
~
运算符代替?
。 - 前缀运算符 (
?int
)。
版权
此文档放置在公有领域或根据 CC0-1.0-Universal 许可证,以更宽松的许可证为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0645.rst
最后修改时间:2023-09-09 17:39:29 GMT