You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python拼接不同类型列表触发MyPy报错如何无需抑制即可解决

问题原因

MyPy进行列表拼接的类型推断时,会优先以最左侧列表的类型作为整个表达式的基准类型。你写的[A1]会被默认推断为List[Type[A1]],而列表是不变型容器,不允许自动向上转型到更宽的List[Union[Sequence[Type[A]], Type[A]]]类型,后续拼接Type[A2]和嵌套列表的时候就会触发类型不匹配错误。手动直接构造完整列表时,MyPy会扫描所有元素来推断类型,所以不会出现这个问题。

解决方案

方案1:显式标注临时变量的类型

提前声明拼接结果的类型,让MyPy按照指定的宽类型做校验,不会自动窄化,该方案无运行时代价,也不需要修改原有类型定义:

#!/usr/bin/python3
from typing import Union, List, NewType, Type, Sequence

class A:
    pass

class A1(A):
    pass

class A2(A):
    pass

B = NewType("B", Sequence[Union[Sequence[Type[A]], Type[A]]])

# 显式标注临时变量的目标类型
temp: Sequence[Union[Sequence[Type[A]], Type[A]]] = [A1] + [A2]*2 + [[A1, A2]]
b1 = B(temp)
b2 = B([A1, A2, [A1, A2]])

方案2:显式转换首个列表的类型

如果不想单独声明临时变量,可以用typing.cast直接指定最左侧列表的类型,打断MyPy的自动窄化推断:

from typing import cast

b1 = B(cast(list[Union[Sequence[Type[A]], Type[A]]], [A1]) + [A2]*2 + [[A1, A2]])

方案3:先创建空列表再逐个添加元素

空列表默认会根据后续添加的元素推断更宽的类型,也可以规避列表拼接的类型推断问题:

temp = []
temp.append(A1)
temp.extend([A2]*2)
temp.append([A1, A2])
b1 = B(temp)

以上三种方案都不需要添加# type: ignore抑制MyPy校验,完全符合类型规范。


内容的提问来源于stack exchange,提问作者Hait

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:45:00