如何使用类型提示指定“可为空”返回类型

Posted

技术标签:

【中文标题】如何使用类型提示指定“可为空”返回类型【英文标题】:How to specify "nullable" return type with type hints 【发布时间】:2017-01-18 15:56:30 【问题描述】:

假设我有一个函数:

def get_some_date(some_argument: int=None) -> %datetime_or_None%:
    if some_argument is not None and some_argument == 1:
        return datetime.utcnow()
    else:
        return None

如何指定可以是None 的返回类型?

【问题讨论】:

typing 包中应用了错误的命名。它可以是Nullable[X],相当于Union[None, X]。因此无需解释Optional 不是可选参数docs.python.org/3/library/typing.html#typing.Optional 【参考方案1】:

您正在寻找Optional

由于您的返回类型可以是datetime(从datetime.utcnow() 返回)或None,您应该使用Optional[datetime]

from typing import Optional

def get_some_date(some_argument: int=None) -> Optional[datetime]:
    # as defined

从有关打字的文档中,Optional 是以下的简写:

Optional[X] 等价于Union[X, None]

其中Union[X, Y] 表示XY 类型的值。


如果您因为担心其他人可能会偶然发现Optional 而没有意识到它的含义而想要明确表达,您可以随时使用Union

from typing import Union

def get_some_date(some_argument: int=None) -> Union[datetime, None]:

但我怀疑这是个好主意,Optional 是一个指示性名称,它确实节省了几次击键。

正如 @Michael0x2a 在 cmets 中指出的那样,Union[T, None] 已转换为 Union[T, type(None)],因此此处无需使用 type

在视觉上这些可能不同,但在编程上,在这两种情况下,结果完全相同Union[datetime.datetime, NoneType] 将是存储在 get_some_date.__annotations__* 中的类型:

>>> from typing import get_type_hints
>>> print(get_type_hints(get_some_date))
'return': typing.Union[datetime.datetime, NoneType],
 'some_argument': typing.Union[int, NoneType]

*使用typing.get_type_hints 获取对象的__annotations__ 属性,而不是直接访问它。

【讨论】:

您可以将Union[datetime, type(None)] 简化为Union[datetime, None] -- 根据PEP 484,在类型注释中使用None 始终被视为等同于type(None)。 (typing 文档在大多数情况下实际上使用了None,但这里没有,这是一个疏忽)。 @Michael0x2a 不知道,很有趣。添加它:) 我刚刚提交了a patch 来解决这个问题,所以希望在不久的将来文档会更加一致! Optional[T] 类型在函数式编程社区中是众所周知的。读者不仅会知道它的意思是Union[T, None],而且会认识到当没有有意义的答案、出现错误或找不到结果时,函数应该返回None的使用模式。 在 Python 3.10 datetime | None 可以使用。【参考方案2】:

您可以只使用类似于 OR 运算符(垂直线 | ):

def get_some_date(some_argument: int=None) -> datetime | None:
   # rest of code

【讨论】:

请注意,OR 运算符 | 仅适用于 Python 3.10+ 中的类型提示 @PApostol 或在 Python 3.7+ 中使用from __future__ import annotations

以上是关于如何使用类型提示指定“可为空”返回类型的主要内容,如果未能解决你的问题,请参考以下文章

可空引用类型:如何指定“T?”类型不限于类或结构

如何识别泛型类型的可为空引用类型?

SQL Server查询指定表格字段类型长度是否可为空等等信息

如何将 CheckBox 绑定到可为空的布尔类型 DbColumn?

如何使用类型提示指定多个返回? [复制]

Pyspark 可为空的 uuid 类型 uuid 但表达式的类型为字符变化