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

如何为子类实例列表做类型注解并合并列表通过mypy类型检查?

解决方法

这里有几个不用# type: ignore就能让mypy通过的方案,核心是解决列表类型不变性带来的类型不兼容问题:

1. 显式标注子类列表的类型为父类列表

既然Cat是Animal的子类,你可以直接把cats的类型声明为list[Animal],这样它和animals的类型就完全匹配,+运算自然能通过mypy检查:

cats: list[Animal] = [Cat(height=1, weight=2, lives=7), Cat(height=3, weight=2, lives=1)]
animals = [Animal(height=9, weight=9)]
combined: Iterable[Animal] = cats + animals

mypy会认可这种标注,因为Cat实例完全符合Animal的类型要求。

2. 使用itertools.chain合并迭代器

如果你不想修改原列表的类型标注,可以用itertools.chain来合并两个可迭代对象。因为Iterable[Cat]是Iterable[Animal]的协变子类型,mypy会允许这种合并:

from itertools import chain

cats = [Cat(height=1, weight=2, lives=7), Cat(height=3, weight=2, lives=1)]
animals = [Animal(height=9, weight=9)]
combined: Iterable[Animal] = chain(cats, animals)

这种方式不会创建新的列表,而是返回一个迭代器,遍历效果和列表一致,还能节省内存。

3. 显式转换子类列表的类型

如果你需要保留cats原有的list[Cat]类型,又想合并后得到list[Animal],可以显式转换类型:

cats = [Cat(height=1, weight=2, lives=7), Cat(height=3, weight=2, lives=1)]
animals = [Animal(height=9, weight=9)]
combined: list[Animal] = list[Animal](cats) + animals

不过这种方式会创建新的列表对象,相比第一种方法稍显繁琐。

为什么原代码会报错?

Mypy对列表类型采用**不变性(invariant)**检查——虽然Cat是Animal的子类,但list[Cat]并不被认为是list[Animal]的子类型。列表的类型参数不会随子类关系协变,所以直接用+合并list[Cat]和list[Animal]时,mypy会判定这两种类型不兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:17:58