【问题标题】:NoReturn vs. None in "void" functions - type annotations in Python 3.6“void”函数中的 NoReturn 与 None - Python 3.6 中的类型注释
【发布时间】:2018-06-10 19:29:28
【问题描述】:

Python 3.6 支持类型注解,如:

def foo() -> int:
    return 42

但是当一个函数没有返回任何东西时应该使用什么? PEP484 示例大多使用None 作为返回类型,但也有来自typing 包的NoReturn 类型。

所以,问题是什么更可取,什么被认为是最佳实践:

def foo() -> None:
    #do smth

from typing import NoReturn

def foo() -> NoReturn:
    #do smth

【问题讨论】:

  • None的类型不是None,而是NoneType
  • @Willem Van Onsem,根据 PEP484,None 在类型提示中被认为等同于 type(None) 什么是 NoneType

标签: python annotations python-3.6 type-hinting typing


【解决方案1】:

NoReturn 表示函数从不返回值

函数要么不终止,要么总是抛出异常"The typing module provides a special type NoReturn to annotate functions that never return normally. For example, a function that unconditionally raises an exception.."

from typing import NoReturn

def stop() -> NoReturn:
    raise RuntimeError('no way')

也就是说,x = foo_None() 类型有效但可疑,而 x = foo_NoReturn() 无效。

除了永远不会有可分配的结果外,NoReturn 在分支分析中还有其他含义:foo_NoReturn(); unreachable..。在'A NoReturn type is needed #165'票中有进一步的讨论。

为了执行分支分析,有必要知道哪些调用永远不会正常返回。例如sys.exit(总是通过异常返回)和os.exit(从不返回)..

【讨论】:

  • 奇怪的是,对于一个可能抛出异常的函数,Optional[NoReturn] 没有传递 mypy(“错误:缺少返回语句”),即使该函数没有'不返回或返回None ...也许这与NoReturn也是底部类型有关
  • @joel: 因为,至少在概念上,NoReturn 本身不是一个类型,它表示 absense of type 因为有没有关联值,甚至没有None。它甚至不能分配,所以你可能不能(至少肯定不应该)在UnionTypeAlias 等中使用它。
  • @MestreLion 我不关注;类型不必具有值才能成为类型。 Idris 中的 Void 和 Scala 中的 Nothing 就是示例。我看不出你不应该在Union 中使用它的任何类型理论原因。当然它在 python 中不是很有用,但我认为它是有效的
  • @joel 没错,从概念上讲,类型不需要值。但是在f(...) -> type:注解的上下文中,我们指的是返回的类型。它有一个非常具体的含义,而不是一个函数退出的howwhenif 的一般注释。允许这样做需要更改 ->语义,如 PEP 所述
猜你喜欢
  • 1970-01-01
  • 2018-07-20
  • 2019-02-15
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 2016-07-20
  • 1970-01-01
相关资源
最近更新 更多