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

如何正确赋值递归类型集合元素以避免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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:22:19