如何使用类型提示指定"可空"返回类型

exf*_*zik 133 python type-hinting python-3.x python-3.5

假设我有一个功能:

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
Run Code Online (Sandbox Code Playgroud)

如何为可能的内容指定返回类型None

Jim*_*ard 204

你在找Optional.

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

from typing import Optional

def get_some_date(some_argument: int=None) -> Optional[datetime]:
    # as defined
Run Code Online (Sandbox Code Playgroud)

从关于打字的文档,Optional是简写:

Optional[X]相当于Union[X, None].

where Union[X, Y]表示类型X或值的值Y.


如果由于担心其他人可能偶然发现Optional并且没有意识到它的含义而想要明确,那么您总是可以使用Union:

from typing import Union

def get_some_date(some_argument: int=None) -> Union[datetime, None]:
Run Code Online (Sandbox Code Playgroud)

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

正如@ Michael0x2a的评论所指出的那样转变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]}
Run Code Online (Sandbox Code Playgroud)

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

  • 您可以根据[PEP 484](https://www.python.org/dev/peps/pep-0484/)将`Union [datetime,type(None)]`简化为`Union [datetime,None]`. #using-none),在类型注释中使用`None`总是被视为等同于`type(None)`.(在大多数情况下,`typing`文档实际上使用`None`,但这里没有,这是一个疏忽). (8认同)
  • 在 Python 3.10 中 `datetime | 没有`可以使用。 (5认同)
  • 我继续提交[补丁](http://bugs.python.org/issue28073)来解决这个问题,所以希望文档在不久的将来会更加一致! (4认同)
  • `Optional[T]` 类型在函数式编程社区中是众所周知的。读者不仅会知道它的意思是“Union[T, None]”,还会认识到当没有有意义的答案、出现错误或找不到结果时,函数将返回 None 的使用模式。 (3认同)

ela*_*no7 56

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

def get_some_date() -> datetime | None:
   # rest of code
Run Code Online (Sandbox Code Playgroud)

  • 请注意,OR 运算符“|”仅适用于 Python 3.10+ 中的类型提示 (36认同)
  • @PApostol 或者在 Python 3.7+ 中使用“from __future__ import comments”。 (20认同)