使用typing.Literal的正确方式是什么?

3

我的代码看起来像这样,在没有任何错误的情况下可以很好地运行BDW。

from typing import Literal

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

a = verify('XY')

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

注意:只需在安装了mypy之后执行mypy ./filename.py即可执行类型检查。

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

from typing import Literal

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

a = verify('XY')

我错过了什么?


1
你能否澄清一下你要做什么?函数的输入方式不太合理 - 它可以返回任何以“Hello”开头的字符串,而不仅仅是'Hello XY'。请注意,类型注释只是这样 - 它们不会影响代码现在的行为或其是否正确(除非某些代码明确地检查注释)。 - MisterMiyagi
1个回答

7

word可以是任意字符串,所以这似乎是个好事情,因为mypy会抱怨它无法猜到你总是会用适当的参数调用它。换句话说,对于mypy来说,如果你将'Hello '与某个str连接起来,它可以给出任何str,而不仅仅是'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

请注意,仍然需要进行类型转换,因为mypy无法猜测将'Hello 'Literal['there', 'world']进行连接的结果是hello_t类型。

你好@qouify,感谢你的解释。我明白我错在哪里了。不过我还有一个问题与你回答的第二部分有关。为什么我们需要在这里进行类型转换,它到底是做什么的?我试着去尝试一下,但是我无法理解。当我执行cast('abc', 'abc')时,它返回'abc',而当我执行cast('abc', 'xyz')时,它返回'xyz'。 - archit jain
2
cast 不会执行任何操作:它只是返回其第二个参数。像 cast(int, i) 这样的表达式的唯一目的是告诉 mypy 必须将 i 视为一个 int 类型。你可以把它看作是一个注释,用于指导 mypy。但它在运行时没有任何影响:你可以从程序中删除 cast,它仍然可以正常运行。 - qouify

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