如何正确赋值递归类型集合元素以避免mypy类型错误?
解决mypy递归类型列表赋值报错的方案
针对你遇到的问题:定义递归类型NestedStringSequence = list[Union[str, "NestedStringSequence"]]后,仅向该类型列表中添加列表元素,但mypy仍认为pop()可能返回str,导致赋值报错,且不想使用cast或重载list.pop()的情况,提供以下合理解决方法:
方法1:拆分类型,明确栈的专属类型
既然栈中只会存储NestedStringSequence(即列表类型),可以单独定义栈的类型,与通用的递归嵌套序列类型区分,让mypy能精确推断元素类型:
from typing import Union, List NestedStringSequence = list[Union[str, "NestedStringSequence"]] # 栈的元素仅为NestedStringSequence类型 StackType = List[NestedStringSequence] element: NestedStringSequence = [] stack: StackType = [element] stack.append([]) element = stack.pop() # mypy可正确推断返回类型为NestedStringSequence,无报错
方法2:使用Protocol约束栈操作
通过定义Protocol来约束栈的append和pop方法的类型,让mypy识别栈中元素的实际类型,无需修改原有列表结构:
from typing import Union, Protocol, runtime_checkable NestedStringSequence = list[Union[str, "NestedStringSequence"]] @runtime_checkable class ListStack(Protocol): def append(self, item: NestedStringSequence) -> None: ... def pop(self) -> NestedStringSequence: ... element: NestedStringSequence = [] stack: ListStack = [element] # 原生列表兼容该Protocol stack.append([]) element = stack.pop() # 类型匹配,无报错
方法3:局部类型窄化(临时场景适用)
在局部代码块中,通过类型检查语句让mypy窄化pop()返回值的类型,虽然会多一行判断,但无需修改类型定义:
from typing import Union NestedStringSequence = list[Union[str, "NestedStringSequence"]] element: NestedStringSequence = [] stack: NestedStringSequence = [element] stack.append([]) popped_item = stack.pop() # 利用类型检查让mypy确认返回值为列表类型 if isinstance(popped_item, list): element = popped_item
内容的提问来源于stack exchange,提问作者frans
相关产品推荐
相关产品推荐

