【问题标题】:What is the correct way of using typing.Literal?使用typing.Literal的正确方法是什么?
【发布时间】:2021-11-24 19:48:00
【问题描述】:

我的代码看起来像这样,它运行良好的 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']")

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

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

from typing import Literal

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

a = verify('XY')

我错过了什么?

【问题讨论】:

  • 你能澄清一下你想要做什么吗?键入函数的方式并不明智——它可以返回以'Hello ' 开头的任意字符串,而不仅仅是'Hello XY'。请注意,类型注释就是这样——它们不会影响代码现在的行为是否正确(除非某些代码显式检查注释)。

标签: python type-hinting mypy typechecking python-typing


【解决方案1】:

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'。
  • cast 不做任何事情:它只是返回它的第二个参数。像cast(int, i) 这样的表达式的唯一目的是告诉mypy i 必须被视为int。您可以将其视为此处用于指导 mypy 的注释。但它没有运行时含义:你可以从你的程序中删除你的cast,它会运行得很好。
猜你喜欢
  • 1970-01-01
  • 2021-09-23
  • 2017-04-07
  • 2013-01-09
  • 2013-03-19
  • 2019-05-11
  • 2018-02-17
  • 2022-01-07
  • 2012-05-17
相关资源
最近更新 更多