Python中不同结构列表相加的mypy类型标注问题
问题原因
mypy 是静态类型检查工具,会自动为未显式标注的变量推导最精确的窄类型:
- 示例中 x 的元素均为
Tuple[str, str]类型,因此被推导为List[Tuple[str, str]] - y 的元素为
Tuple[str, List[Tuple[str, str]]]类型,因此被推导为List[Tuple[str, List[Tuple[str, str]]]]
Python 运行时列表允许存储任意类型元素,因此相加可以正常执行,但 mypy 默认要求列表加法的两个操作数元素类型必须兼容,相加后得到的新列表元素类型和操作数一致,上述两个列表的元素类型无交集,因此触发类型报错。
解决方法
方案1:显式标注列表的元素为联合类型(推荐)
如果你明确知晓列表会存储两种结构的元组,可以手动标注列表的元素类型为两类元组的联合类型,让 mypy 认可类型兼容性。后续操作新列表中的元素时,可以通过判断第二个元素的类型做类型窄化,mypy 会完成对应的类型校验,不会出现误报。
Python 3.10 及以上版本可直接用 | 表示联合类型:
# check.py x: list[tuple[str, str] | tuple[str, list[tuple[str, str]]]] = [("a", "b"), ("c", "d")] y = [("x", [("1", "2"), ("3", "4")])] z = x + y
Python 3.9 及以下版本需要从 typing 模块导入 Union 使用:
from typing import Union, List, Tuple # check.py x: List[Union[Tuple[str, str], Tuple[str, List[Tuple[str, str]]]]] = [("a", "b"), ("c", "d")] y = [("x", [("1", "2"), ("3", "4")])] z = x + y
方案2:临时忽略类型检查(不推荐)
如果只是临时调试不需要严格校验,可以在报错行添加忽略注释,mypy 会跳过该行的类型检查:
x = [("a", "b"), ("c", "d")] y = [("x", [("1", "2"), ("3", "4")])] z = x + y # type: ignore[operator]
内容的提问来源于stack exchange,提问作者baxx
相关产品推荐
相关产品推荐

