Python空类型注解

272
在Python 3.x中,通常会使用函数的返回类型注解,例如:
def foo() -> str:
    return "bar"

对于"void"类型,正确的注释是什么?

我考虑了3个选项:

  1. def foo() -> None:
    • 在我看来不太合逻辑,因为None不是一个类型。
  2. def foo() -> type(None):
    • 使用我所知道的最佳语法来获取NoneType
  3. def foo():
    • 省略显式的返回类型信息。

对我来说,选项2似乎是最合理的选择,但我已经看到过一些1的实例。


41
Python中没有返回值类型为void的函数。任何没有显式return语句的函数(或函数中的分支)都会返回None。我假设原帖作者理解这一点,这条评论主要是为了未来读者的利益... - PM 2Ring
嗯,这个问题并不像“为什么我的Python函数返回None?”(我编造了这个问题)那样受欢迎,所以大多数读者可能已经知道默认行为。1与2的困境在答案中得到解决。但是对于3呢?对于“过程”,我实际上更喜欢选项3,没有无用的杂物(毕竟,这个函数不返回任何东西)。 - Tomasz Gandor
@TomaszGandor 同意。当一个函数或方法不包含返回语句时,指定其返回类型是没有必要的。 - Jeyekomon
使用None进行类型提示似乎并不合理,因为它本身并不是一种类型,除非你知道在内部None被解释为type(None),也就是NoneType - starriet
2个回答

297
这是直接从PEP 484 -- Type Hints文档中摘录的:
在类型提示中使用时,表达式None被视为等同于type(None)
正如您所看到的,大多数示例使用None作为返回类型。

50
为了澄清,选择上述的选项1。 - Adam Nelson
14
NoReturn类型怎么样?请参考https://www.python.org/dev/peps/pep-0484/#the-noreturn-type。 - asmaier
28
根据这个问题,引用了PEP 484 - 类型提示的内容,NoReturn类型被用来"......注释永远不会正常返回的函数。例如,无条件引发异常的函数......" - Rodrigo Laguna
补充一下,有一个名为NoneType的类,它与None不同(None != type(None))。如果您正在检查带有-> None类型提示的函数的返回类型,则应检查typing.get_type_hints(func)['return'] == type(None)。 - malanb5
另外值得一提的是,VS Code 喜欢 1,而不是 2。我刚开始使用 VS Code,所以请不要把我当成专家。 - RadlyEel

135
TLDR: 一个 void 返回类型注释的习惯用法等价于 -> None
def foo() -> None:
    ...

这意味着没有 return 或只有一个裸露的 return 的函数会被评估为 None

def void_func():  # unannotated void function
    pass

print(void_func())  # None

省略返回类型并不意味着没有返回值。根据PEP 484
对于已经过检查的函数,参数和返回类型的默认注释为Any
这意味着该值被认为是动态类型且静态支持任何操作,这实际上与void的相反含义。
在Python中,类型提示并不严格要求实际类型。例如,注释可以使用类型名称的字符串:Union[str, int]Union[str, 'int']'Union[str, int]'和各种变体都是等效的。
同样,类型注释None被认为是表示“属于NoneType”。这也可以用于其他情况,而不仅仅是返回类型,尽管你最常见到的是作为返回类型注释。
bar : None

def foo(baz: None) -> None:
    return None

这也适用于通用类型。例如,您可以在Generator[int, None, None]中使用None来表示生成器不接受或返回值。
尽管PEP 484建议使用None表示type(None),但您不应明确使用后者形式。类型提示规范不包括任何形式的type(...)。这在技术上是一种运行时表达式,其支持完全取决于类型检查器。mypy项目正在考虑是否删除type(None)的支持,并将其从PEP 484中删除。

或者,我们应该更新PEP 484,不建议使用type(None)作为类型,而是只使用None?应该有一种 -- 最好只有一种 -- 显而易见的方法来做到这一点等。

--- JukkaL, 2018年5月18日


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接