gpt4 book ai didi

python - Mypy 因重载和文字而失败

转载 作者:行者123 更新时间:2023-12-05 01:49:59 27 4
gpt4 key购买 nike

我正在尝试理解 typing.overload 并将其应用到一个简单的案例中,我想要一个接受输入的函数 x: Literal["foo", "bar"] 并返回列表 [x]

我希望 mypy 根据x 的值。

我知道我可以使用 TypeVar 实现这一点,但我仍然想了解为什么下面的代码会失败并出现以下错误:

test.py:14: error: Overloaded function implementation cannot produce return type of signature 1
test.py:14: error: Overloaded function implementation cannot produce return type of signature 2
from typing import Literal, overload


@overload
def f(x: Literal["foo"]) -> list[Literal["foo"]]:
...


@overload
def f(x: Literal["bar"]) -> list[Literal["bar"]]:
...


def f(x: Literal["foo", "bar"]) -> list[Literal["foo", "bar"]]:
return [x]

最佳答案

Python 中的列表是不变的。这意味着,即使 BA 的子类型,类型之间没有关系 list[A]list[B] .

如果list[B]被允许成为 list[A] 的子类型, 然后有人可以来做这件事。

my_b_list: list[B] = []
my_a_list: list[A] = my_b_list
my_a_list.append(A())
print(my_b_list) # Oh no, a list[B] contains an A value!

如果您打算修改返回的列表,那么您所做的是不安全的。故事结局。如果您计划将列表视为不可变的,那么请考虑您实际需要什么操作,并且您可能能够找到 list 的协变父类(super class)型。在 typing .

例如, Sequence 是一个受欢迎的选择。它支持迭代、随机访问和长度访问,同时明确不允许允许突变。

from typing import Literal, overload, Sequence


@overload
def f(x: Literal["foo"]) -> Sequence[Literal["foo"]]:
...


@overload
def f(x: Literal["bar"]) -> Sequence[Literal["bar"]]:
...


def f(x: Literal["foo", "bar"]) -> Sequence[Literal["foo", "bar"]]:
return [x]

(注意:typing.Sequence 在 Python 3.9 中已弃用;如果您只打算支持 3.9+,则可以改用 collections.abc.Sequence)

关于python - Mypy 因重载和文字而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73557943/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com