Python 3.10+:可选[类型]或类型|无

问题描述 投票:0回答:5

现在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 type-hinting mypy python-typing python-3.10
5个回答
74
投票

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

现有的

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

int | str == typing.Union[int, str]

联盟中项目的顺序与平等无关。

(int | str) == (str | int)
(int | str | float) == typing.Union[str, float, int]

可选值应等同于新的联合语法

None | t == typing.Optional[t]

由于 @jonrsharpe 评论

Union
Optional
并未弃用,因此
Union
|
语法是可以接受的。


Python 核心开发人员

Łukasz Langa 在与 Python 3.10 版本相关的 YouTube 直播中回复称,对于 Python 3.10+,

Type | None
优于
Optional[Type]


25
投票

我个人会继续选择选项 2

另外,只是想添加这个以提高认识,但 Python 3.7+ 可以使用

__future__
导入来支持此语法,如下所示。这种类型的检查是一样的;实际上,我从我目前正在使用的 Pycharm 的最新发行说明中得到了提示。

from __future__ import annotations


def f(parameter: int | None) -> str | None:
    ...

7
投票

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

如果您要声明默认值,请将其输入为

def foo(bar: Optional[int] = None)
,它声明了您不必传递参数的显式意图。

但是,如果您没有默认值,则可以声明它

def foo(bar: int | None)
,它声明这是一个必需参数,其中
None
是有效参数值之一。

大多数时候,你想做前者,所以大多数时候你仍然应该使用

Optional[int]
;但在某些情况下,要求调用者显式传递 None 可能是可取的。

第二个原因是写

def foo(bar: int | None = None)
看起来很难看,并且与重复的
None
混淆。


4
投票

非权威,但我希望

Optional
何时

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

虽然我希望在

时使用一些
Union
|

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

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


0
投票

在返回封闭类的类型的特定情况下,您仍然需要使用

Optional
即使是python3.10+。从 python3.11.6 开始仍然如此。

例如:

# temp.py
class A:
    def __init__(self):
        print("init")

    def test(self) -> "A" | None:
        pass

尝试运行

temp.py
会遇到
TypeError
:

$ python3.11 temp.py
Traceback (most recent call last):
  File "/Users/vietthan/Documents/temp.py", line 1, in <module>
    class A:
  File "/Users/vietthan/Documents/temp.py", line 5, in A
    def test(self) -> "A" | None:
                      ~~~~^~~~~~
TypeError: unsupported operand type(s) for |: 'str' and 'NoneType'

我检查了 mypy、black、ruff,它们都没有发现这个错误。

© www.soinside.com 2019 - 2024. All rights reserved.