问题:Python void返回类型注释

在python 3.x中,通常使用函数的返回类型注释,例如:

def foo() -> str:
    return "bar"

“ void”类型的正确注释是什么?

我正在考虑3个选择:

  1. def foo() -> None:
    • 不是逻辑IMO,因为None不是类型,
  2. def foo() -> type(None):
    • 使用我知道的最佳语法NoneType
  3. def foo():
    • 省略显式的返回类型信息。

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

In python 3.x, it is common to use return type annotation of a function, such as:

def foo() -> str:
    return "bar"

What is the correct annotation for the “void” type?

I’m considering 3 options:

  1. def foo() -> None:
    • not logical IMO, because None is not a type,
  2. def foo() -> type(None):
    • using the best syntax I know for obtaining NoneType,
  3. def foo():
    • omit explicit return type information.

Option 2. seems the most logical to me, but I’ve already seen some instances of 1.


回答 0

这直接来自PEP 484-类型提示文档:

在类型提示中使用时,该表达式None被认为等效于type(None)

而且,如您所见,大多数示例都None用作返回类型。

This is straight from PEP 484 — Type Hints documentation:

When used in a type hint, the expression None is considered equivalent to type(None).

And, as you can see most of the examples use None as return type.


回答 1

TLDR:void返回类型注释的惯用等效项是-> None

def foo() -> None:
    ...

这符合,如果没有一个函数return或只是一个光秃秃return的计算结果为None

def void_func():  # unannotated void function
    pass

print(void())  # None

省略返回类型也并不意味着就没有返回值。根据PEP 484

对于选中的函数,参数和返回类型的默认注释为Any

这意味着该值被认为是动态类型的,并且静态地支持任何操作。这实际上是的相反含义void


Python中的类型提示并不严格要求实际类型。例如,注释可以使用类型名称为Union[str, int],,的字符串Union[str, 'int']'Union[str, int]'并且各种变体是等效的。

同样,类型注释None被认为 “ is of NoneType”。这不仅可以用于返回类型,尽管您会经常在以下位置看到它:

bar : None

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

这也适用于泛型类型。例如,您可以使用Nonein Generator[int, None, None]指示生成器不接受也不返回值。


即使PEP 484建议采用这种None方式type(None),您也不应明确使用后者。该类型提示规范并没有包括任何形式的type(...)。从技术上讲,这是一个运行时表达式,其支持完全取决于类型检查器。该mypy项目正在考虑取消type(None)484的支持并将其也从484中删除。

或者,也许我们应该更新PEP 484以不建议该type(None)类型有效。None是唯一正确的拼写吗?应该有一种-最好只有一种-明显的方式来做等。

JukkaL,2018年5月18日

TLDR: The idiomatic equivalent of a void return type annotation is -> None.

def foo() -> None:
    ...

This matches that a function without return or just a bare return evaluates to None.

def void_func():  # unannotated void function
    pass

print(void())  # None

Omitting the return type does not mean that there is no return value. As per PEP 484:

For a checked function, the default annotation for arguments and for the return type is Any.

This means the value is considered dynamically typed and statically supports any operation. That is practically the opposite meaning of void.


Type hinting in Python does not strictly require actual types. For example, annotations may use strings of type names: Union[str, int], Union[str, 'int'], 'Union[str, int]' and various variants are equivalent.

Similarly, the type annotation None is considered to mean “is of NoneType“. This can be used not just for return types, though you will see it most often there:

bar : None

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

This also applies to generic types. For example, you can use None in Generator[int, None, None] to indicate a generator does not take or return values.


Even though PEP 484 suggests that None means type(None), you should not use the latter form explicitly. The type hinting specification does not include any form of type(...). This is technically a runtime expression, and its support is entirely up to the type checker. The mypy project is considering to remove support for type(None) and remove it from 484 as well.

Or maybe we should update PEP 484 to not suggest that type(None) is valid as a type, and None is the only correct spelling? There should one — and preferably only one — obvious way to do it etc.

JukkaL, 18 May 2018


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。