"void"函数中的NoReturn与None - 在Python 3.6中键入注释

ByA*_*enT 7 python annotations typing type-hinting python-3.6

Python 3.6支持类型注释,如:

def foo() -> int:
    return 42
Run Code Online (Sandbox Code Playgroud)

但是当函数没有返回任何内容时,预期会使用什么?PEP484示例主要None用作返回类型,但也有包中的NoReturn类型typing.

所以,问题是什么是更好的使用和什么被认为是最佳实践:

def foo() -> None:
    #do smth
Run Code Online (Sandbox Code Playgroud)

要么

from typing import NoReturn

def foo() -> NoReturn:
    #do smth
Run Code Online (Sandbox Code Playgroud)

use*_*740 10

NoReturn表示函数永远不会返回值.

该函数要么不终止,要么总是抛出异常:"输入模块提供了一个特殊的类型NoReturn来注释永远不会正常返回的函数.例如,一个无条件地引发异常的函数.".

from typing import NoReturn

def stop() -> NoReturn:
    raise RuntimeError('no way')
Run Code Online (Sandbox Code Playgroud)

也就是说,x = foo_None()类型有效但怀疑x = foo_NoReturn()是无效的.

除了没有可分配的结果外,NoReturn在分支分析中也有其他含义:foo_NoReturn(); unreachable...在'A NoReturntype is needed#165'票证中有进一步的讨论.

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

  • 奇怪的是,对于可能抛出异常的函数,“Optional[NoReturn]”不会传递 mypy(“错误:缺少 return 语句”),即使该函数不返回或返回“None”...也许这与“NoReturn”也是底部类型有关 (2认同)
  • @OliverAngelil 您对返回“None”的函数使用“-> None”。当然,这听起来很明显。当我开始对自己的代码进行类型注释时,我忽略的是没有显式“return”语句的函数将具有_隐式_“return None”。因此,您的示例函数将是“def foo() -> None”。如果你有一个不带参数的“return”,则相同:“return”的参数隐式为“None”。 (2认同)