输入函数永远不会 returns 的提示
Type hint that a function never returns
Python 的新 type hinting 功能允许我们键入提示函数 returns None
...
def some_func() -> None:
pass
... 或者不指定 return 类型,PEP 规定这应该导致静态分析器假定任何 return 类型都是可能的:
Any function without annotations should be treated as having the most general type possible
但是,我应该如何输入函数永远不会 return 的提示?例如,键入提示这两个函数的 return 值的正确方法是什么?
def loop_forever():
while True:
print('This function never returns because it loops forever')
def always_explode():
raise Exception('This function never returns because it always raises')
在这些情况下,既不指定 -> None
也不保留 return 类型未指定似乎是正确的。
2016年7月,这个问题还没有答案(现在有NoReturn
;见)。这些是一些原因:
当函数不 return 时,没有 return 值(甚至 None
)可以分配类型。因此,您实际上并不是在尝试注释类型;您正在尝试注释 缺少类型 。
从 Python 版本 3.5 开始,类型提示 PEP 才刚刚被标准采用。此外,PEP 只建议 应该是什么样的类型注释 ,而在 如何使用它们 上故意含糊其辞。因此,除了示例之外,没有任何标准告诉我们具体如何做任何事情。
PEP 有一段 Acceptable type hints 说明如下:
Annotations must be valid expressions that evaluate without raising exceptions at the time the function is defined (but see below for forward references).
Annotations should be kept simple or static analysis tools may not be able to interpret the values. For example, dynamically computed types are unlikely to be understood. (This is an intentionally somewhat vague requirement, specific inclusions and exclusions may be added to future versions of this PEP as warranted by the discussion.)
所以它试图阻止你做过于有创意的事情,比如在 return 类型提示中抛出异常,以表明函数永远不会 returns。
关于例外,the PEP states the following:
No syntax for listing explicitly raised exceptions is proposed. Currently the only known use case for this feature is documentational, in which case the recommendation is to put this information in a docstring.
在 type comments 上有一个建议,你有更多的自由,但即使那个部分也没有讨论如何记录类型的缺失。
在稍微不同的情况下,您可以尝试一件事,当您想要暗示某个 "normal" 函数的参数或 return 值应该是一个永远不会 return秒。 syntax 是 Callable[[ArgTypes...] ReturnType]
,因此您可以省略 return 类型,如 Callable[[ArgTypes...]]
。但是,这不符合推荐的语法,因此严格来说它不是可接受的类型提示。类型检查器可能会因此而窒息。
结论:你超前了。这可能令人失望,但对您也有好处:您仍然可以影响非 returning 函数的注释方式。也许这将成为您参与标准化过程的借口。 :-)
我有两个建议。
允许在 Callable
提示中省略 return 类型 和 允许向前提示任何类型。这将导致以下语法:
always_explode: Callable[[]]
def always_explode():
raise Exception('This function never returns because it always raises')
引入一个bottom type like in Haskell:
def always_explode() -> ⊥:
raise Exception('This function never returns because it always raises')
这两个建议可以合并。
尽管“PEP 484 — Type Hints” standard mentioned both in question and in the answer yet nobody quotes its section: The NoReturn
type 涵盖了您的问题。
引用:
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')
该部分还提供了错误用法的示例。尽管它没有涵盖具有无限循环的函数,但在类型理论中它们都同样满足 never returns 由该特殊类型表达的含义。
Python 的新 type hinting 功能允许我们键入提示函数 returns None
...
def some_func() -> None:
pass
... 或者不指定 return 类型,PEP 规定这应该导致静态分析器假定任何 return 类型都是可能的:
Any function without annotations should be treated as having the most general type possible
但是,我应该如何输入函数永远不会 return 的提示?例如,键入提示这两个函数的 return 值的正确方法是什么?
def loop_forever():
while True:
print('This function never returns because it loops forever')
def always_explode():
raise Exception('This function never returns because it always raises')
在这些情况下,既不指定 -> None
也不保留 return 类型未指定似乎是正确的。
2016年7月,这个问题还没有答案(现在有NoReturn
;见
当函数不 return 时,没有 return 值(甚至
None
)可以分配类型。因此,您实际上并不是在尝试注释类型;您正在尝试注释 缺少类型 。从 Python 版本 3.5 开始,类型提示 PEP 才刚刚被标准采用。此外,PEP 只建议 应该是什么样的类型注释 ,而在 如何使用它们 上故意含糊其辞。因此,除了示例之外,没有任何标准告诉我们具体如何做任何事情。
PEP 有一段 Acceptable type hints 说明如下:
Annotations must be valid expressions that evaluate without raising exceptions at the time the function is defined (but see below for forward references).
Annotations should be kept simple or static analysis tools may not be able to interpret the values. For example, dynamically computed types are unlikely to be understood. (This is an intentionally somewhat vague requirement, specific inclusions and exclusions may be added to future versions of this PEP as warranted by the discussion.)
所以它试图阻止你做过于有创意的事情,比如在 return 类型提示中抛出异常,以表明函数永远不会 returns。
关于例外,the PEP states the following:
No syntax for listing explicitly raised exceptions is proposed. Currently the only known use case for this feature is documentational, in which case the recommendation is to put this information in a docstring.
在 type comments 上有一个建议,你有更多的自由,但即使那个部分也没有讨论如何记录类型的缺失。
在稍微不同的情况下,您可以尝试一件事,当您想要暗示某个 "normal" 函数的参数或 return 值应该是一个永远不会 return秒。 syntax 是 Callable[[ArgTypes...] ReturnType]
,因此您可以省略 return 类型,如 Callable[[ArgTypes...]]
。但是,这不符合推荐的语法,因此严格来说它不是可接受的类型提示。类型检查器可能会因此而窒息。
结论:你超前了。这可能令人失望,但对您也有好处:您仍然可以影响非 returning 函数的注释方式。也许这将成为您参与标准化过程的借口。 :-)
我有两个建议。
允许在
Callable
提示中省略 return 类型 和 允许向前提示任何类型。这将导致以下语法:always_explode: Callable[[]] def always_explode(): raise Exception('This function never returns because it always raises')
引入一个bottom type like in Haskell:
def always_explode() -> ⊥: raise Exception('This function never returns because it always raises')
这两个建议可以合并。
尽管“PEP 484 — Type Hints” standard mentioned both in question and in the answer yet nobody quotes its section: The NoReturn
type 涵盖了您的问题。
引用:
The
typing
module provides a special typeNoReturn
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')
该部分还提供了错误用法的示例。尽管它没有涵盖具有无限循环的函数,但在类型理论中它们都同样满足 never returns 由该特殊类型表达的含义。