使用 types.Literal 的正确方法是什么?

arc*_*ain 3 python typechecking type-hinting mypy python-typing

我的代码看起来像这样,BDW 运行良好,没有任何错误

from typing import Literal

def verify(word: str) -> Literal['Hello XY']:
    a = 'Hello ' + word
    return a

a = verify('XY')
Run Code Online (Sandbox Code Playgroud)

虽然,当我尝试使用 mypy 进行类型检查时,它会抛出错误error: Incompatible return value type (got "str", expected "Literal['Hello XY']")

注意:要执行类型检查mypy ./filename.py,只需在 pip 安装 mypy 后执行 。

另外,当我这样做时,类型检查工作正常

from typing import Literal

def verify(word: str) -> Literal['Hello XY']:
    a = 'Hello ' + word
    return 'Hello XY' #changed here

a = verify('XY')
Run Code Online (Sandbox Code Playgroud)

我缺少什么?

qou*_*ify 7

word可以是任何字符串,所以这似乎是 mypy 抱怨的一件好事,因为它无法猜测您总是会使用适当的参数来调用它。换句话说,对于 mypy,如果您连接'Hello 'some str,它可以给出 anystr而不仅仅是'Hello XY'

您可以执行以下操作来检查该函数是否被正确调用word

from typing import Literal, cast

hello_t = Literal['Hello there', 'Hello world']

def verify(word: Literal['there', 'world']) -> hello_t:
    a = cast(hello_t, 'Hello ' + word)
    return a

a = verify('there')  # mypy OK
a = verify('world')  # mypy OK
a = verify('you')  # mypy error
Run Code Online (Sandbox Code Playgroud)

请注意,仍然需要强制转换,因为 mypy 无法猜测 与'Hello 'a 的串联Literal['there', 'world']的类型为hello_t

  • `cast` 不执行任何操作:它只是返回第二个参数。像“cast(int, i)”这样的表达式的唯一目的是告诉 mypy“i”必须被视为“int”。您可以将其视为放在这里指导 mypy 的注释。但它没有运行时含义:您可以从程序中删除“cast”,它会运行得很好。 (2认同)