在 python 中输入提示空列表作为文字的正确方法是什么?

hou*_*eft 2 python python-typing

我有一个总是返回空列表的函数(这是一个很长的故事),我可以像往常一样只用“list”输入提示,但是指示列表总是相同的会很有用。

我的第一个想法是使用这样的文字:

from typing import Literal

def get_empty_list() -> Literal[[]]:
    return []
Run Code Online (Sandbox Code Playgroud)

Mypy 将其标记为无效类型,是否有正确的方法来输入提示始终为空的列表?(显然,我可以输入提示只是一个列表,但这没什么帮助)

明确地说,这是一个始终为空的列表,并且不希望包含任何元素。(例如,与当前为空的列表分开,但稍后可能添加某种类型的元素)。

use*_*ica 6

如果您想要一个表达“现在没有元素的列表,但以后可能会添加元素”的类型,那么它基本上不是静态类型。将元素附加到此类列表是有效的,但会导致列表不再是该类型的元素,而在尊重静态类型的程序中,静态类型不应发生这种情况。

如果你想要表达“没有元素并且永远不会有元素的列表”的东西,你可以这样做:

from typing import Never

def get_empty_list() -> list[Never]:
    return []
Run Code Online (Sandbox Code Playgroud)

在这里,我们将元素类型注释为typing.Never,一种没有值的类型。如果没有上下文建议另一种类型,这实际上是 mypy 推断空列表文字的类型,如您所见reveal_type

from typing import Never

x: list[Never]
reveal_type(x)
reveal_type([])
Run Code Online (Sandbox Code Playgroud)

mypy 输出:

main.py:4: note: Revealed type is "builtins.list[<nothing>]"
main.py:5: note: Revealed type is "builtins.list[<nothing>]"
Success: no issues found in 1 source file
Run Code Online (Sandbox Code Playgroud)

以下是使用类型的含义list[Never]

  • 静态类型检查器不允许将元素添加到注释为 的列表中的操作list[Never]

  • 它们允许诸如 之类的操作get_empty_list().append(sys.exit()),其中 的参数append是一个无法求值的表达式。

  • 他们会认识到get_empty_list()[0]无法计算出一个值......但这与将其视为禁止的操作有很大不同。事实上,他们不会禁止这种操作,而是在几乎任何情况下都允许这种操作。

    毕竟,如果表达式不能生成值,那么无论正确的类型是什么,它都不能生成错误类型的。所以你可以做类似的事情

    x: int = get_empty_list()[0]
    
    Run Code Online (Sandbox Code Playgroud)

    从静态类型的角度来看,这是完全有效的。([][0]被认为是有效的。)

  • 他们不会认识到它len(get_empty_list())一定是 0。