现在Python 3.10已发布,当指示参数或返回值可能是可选的,即可以为None
时,是否有任何偏好。那么哪个更受欢迎:
选项1:
def f(parameter: Optional[int]) -> Optional[str]:
选项2:
def f(parameter: int | None) -> str | None:
另外,Type | None
和 None | Type
之间有没有任何偏好?
现在Python 3.10已发布,当指示参数或返回值可能是可选的,即可以为None
时,是否有任何偏好。那么哪个更受欢迎:
选项1:
def f(parameter: Optional[int]) -> Optional[str]:
选项2:
def f(parameter: int | None) -> str | None:
另外,Type | None
和 None | Type
之间有没有任何偏好?
PEP 604 在规范部分涵盖了这些主题。
The existing
typing.Union
and|
syntax should be equivalent.
int | str == typing.Union[int, str]
The order of the items in the Union should not matter for equality.
(int | str) == (str | int) (int | str | float) == typing.Union[str, float, int]
Optional values should be equivalent to the new union syntax
None | t == typing.Optional[t]
正如@jonrsharpe的评论所述,Union
和Optional
并未被废弃,因此Union
和|
语法是可以接受的。
Łukasz Langa, 一位Python核心开发者,在与Python 3.10发布相关的YouTube直播中回复说,对于Python 3.10+,Type | None
比Optional[Type]
更受欢迎。
在未来的发展中,我个人会选择第二个选项。
另外,只是想提醒一下,Python 3.7+可以使用__future__
导入来支持此语法,如下所示。这种类型检查与以前相同;实际上,我是从我目前使用的Pycharm的最新发布说明中得到的提示。
from __future__ import annotations
def f(parameter: int | None) -> str | None:
...
def foo(bar: Optional[int] = None)
,这声明了一个明确的意图,即您不必传入参数。def foo(bar: int | None)
,这表示这是一个必需的参数,其中None
是有效参数值之一。Optional[int]
;但是在某些情况下,要求调用者显式传递None可能是可取的。def foo(bar: int | None = None)
看起来很丑,重复的None
也容易混淆。Optional
与参数是否可选无关。而参数 bar = 12
的意思是该参数 bar
是可选的,但绝不是 Optional
。 - MisterMiyagisome_type | None
使代码难以理解,因为管道操作符 |
可以有多种用法。将一个类型和 None
做按位或运算的含义是什么?这非常令人困惑... - Péter Szilvási|
是一个非常常见的表示“或”的符号,@PéterSzilvási,在许多系统中一直延续到上个世纪。它读起来像黄油一样顺畅。 - NeilGOptional
:
None
)None
是不寻常的Union
或|
:
None
None
也是一个有效的值Optional[T]
太啰嗦了,与其他有某种形式的T?
的语言相比。由于类型提示是一个装饰性质的东西,有时候我只会写成foo(comment: str = None)
这样的形式。而且,像__init__()
返回None这样的函数不应该有返回值注释,-> None
看起来让我感觉很糟糕。但这并不是“标准”,使用代码检查工具时可能会有警告。 - Tomasz Gandor
Optional
是为了表示“类型或None”而发明的。它的内在含义就是“类型或None”,所以根据良好的基本原则,使用type | None
更加明确。它还可以摆脱一个标识符。只要你确定你的Python版本支持它,这些都是选择新语法的客观理由。 - NeilG