“void”函数中的 NoReturn 与 None - Python 3.6 中的类型注释
Posted
技术标签:
【中文标题】“void”函数中的 NoReturn 与 None - Python 3.6 中的类型注释【英文标题】:NoReturn vs. None in "void" functions - type annotations in 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
。
【参考方案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
。它甚至不能分配,所以你可能不能(至少肯定不应该)在Union
、TypeAlias
等中使用它。
@MestreLion 我不关注;类型不必具有值才能成为类型。 Idris 中的 Void
和 Scala 中的 Nothing
就是示例。我看不出你不应该在Union
中使用它的任何类型理论原因。当然它在 python 中不是很有用,但我认为它是有效的
@joel 没错,从概念上讲,类型不需要值。但是在f(...) -> type:
注解的上下文中,我们指的是返回的值的类型。它有一个非常具体的含义,而不是一个函数退出的how、when 或if 的一般注释。允许这样做需要更改 ->
的 语义,如 PEP 所述以上是关于“void”函数中的 NoReturn 与 None - Python 3.6 中的类型注释的主要内容,如果未能解决你的问题,请参考以下文章
warning: control reaches end of non-void function
Linux C语言编译警告:control reaches end of non-void function
DllImport Unmanaged, Non .NET Dll to .NET Project 表示 Char * 和 Void __StdCall