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

我希望mypy根据值x将结果列表输入为list[Literal["foo"]]list[Literal["bar"]].

我知道我可以用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]之间也有no relation.

如果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!

如果您计划修改返回的列表,那么您正在做的事情是不安全的.故事结束了.如果您计划将列表视为不可变的,那么考虑您的actually需要哪些操作,您也许能够找到协变超类型list in typing.

例如,Sequence是一个流行的 Select .它支持迭代、随机访问和长度访问,同时明确not允许Mutations .

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在Python3.9中已弃用;如果您只计划支持3.9+,则可以使用collections.abc.Sequence)

Python相关问答推荐

如何用symy更新分段函数

如何在Python中使用时区夏令时获取任何给定本地时间的纪元值?

比较两个数据帧并并排附加结果(获取性能警告)

为什么带有dropna=False的groupby会阻止后续的MultiIndex.dropna()工作?

运行终端命令时出现问题:pip start anonymous"

' osmnx.shortest_track '返回有效源 node 和目标 node 的'无'

大小为M的第N位_计数(或人口计数)的公式

如何从.cgi网站刮一张表到rame?

运输问题分支定界法&

计算天数

如何使用两个关键函数来排序一个多索引框架?

python panda ExcelWriter切换动态公式到数组公式

交替字符串位置的正则表达式

当单元测试失败时,是否有一个惯例会抛出许多类似的错误消息?

将链中的矩阵乘法应用于多组值

提取最内层嵌套链接

上传文件并使用Panda打开时的Flask 问题

仅取消堆叠最后三列

如何在python tkinter中绑定键盘上的另一个回车?

如何将验证器应用于PYDANC2中的EACHY_ITEM?