Python 3.10+:可选[类型]或类型| 没有任何

lmi*_*asf 70 python type-hinting mypy python-typing python-3.10

现在Python 3.10已经发布了,在指示参数或返回值可能是可选的(即可以是None. 那么什么是首选:

选项1:

def f(parameter: Optional[int]) -> Optional[str]:
Run Code Online (Sandbox Code Playgroud)

选项2:

def f(parameter: int | None) -> str | None:
Run Code Online (Sandbox Code Playgroud)

Type | None另外,和之间有什么偏好吗None | Type

Jak*_*kub 80

PEP 604在规范部分涵盖了这些主题。

\n
\n

现有的typing.Union|语法应该是等效的。

\n
int | str == typing.Union[int, str]\n
Run Code Online (Sandbox Code Playgroud)\n
\n
\n

Union 中项目的顺序对于平等来说不重要。

\n
(int | str) == (str | int)\n(int | str | float) == typing.Union[str, float, int]\n
Run Code Online (Sandbox Code Playgroud)\n

可选值应等同于新的 union 语法

\n
None | t == typing.Optional[t]\n
Run Code Online (Sandbox Code Playgroud)\n
\n

由于@jonrsharpe 注释,UnionOptional并未被弃用,因此Unionand|语法是可以接受的。

\n
\n

\xc5\x81ukasz Langa是一位 Python 核心开发人员,他在 YouTube 直播中回复了与 Python 3.10 版本相关的问题,该版本比 Python 3.10+Type | None更受青睐。Optional[Type]

\n

在此输入图像描述

\n

  • 如果我们需要在 YouTube 评论中寻找好的做法,那是一种非常可悲的情况:( (17认同)

rv.*_*tch 26

我个人会继续选择选项 2

另外,只是想添加这个以提高认识,但 Python 3.7+ 可以使用导入来支持此语法,__future__如下所示。这种类型的检查是一样的;实际上,我从我目前正在使用的 Pycharm 的最新发行说明中得到了提示。

from __future__ import annotations


def f(parameter: int | None) -> str | None:
    ...
Run Code Online (Sandbox Code Playgroud)


Lie*_*yan 7

这完全是我的观点,但我认为虽然它们相当于类型检查器,但它们向人类读者表达了非常不同的意图。因此它们不可互换。

如果您要声明默认值,则将其键入为def foo(bar: Optional[int] = None)声明您不必传递参数的显式意图。

但是,如果您没有默认值,则可以声明它def foo(bar: int | None),它声明这是一个必需参数,其中None是有效参数值之一。

大多数时候,您想做前者,所以大多数时候您仍然应该使用Optional[int]; 但在某些情况下,要求调用者显式传递 None 可能是可取的。

第二个原因是,写作def foo(bar: int | None = None)看起来很丑陋,而且与重复的None.

  • 请注意,“可选”与参数可选无关。参数“bar = 12”也意味着参数“bar”是可选的,但绝对不是“可选”。 (12认同)
  • 管道运算符“|”是“或”的极其常见的表示形式,@PéterSzilvási,可以追溯到上个世纪的许多系统。读起来像黄油。 (3认同)

ti7*_*ti7 5

非权威,但我预计Optional什么时候

  • 提供了一个默认值(可能None
  • None呼叫者通过将是不寻常的

虽然我期望一些Union|在什么时候使用

  • 没有默认值和/或没有默认值 None
  • None也是一个有效值

请参阅相关建议:使用类型提示时如何向函数添加默认参数?