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

mypy严格模式下二叉树操作函数报Optional[Tree]类型不匹配错误如何解决

问题原因

Tree类的left、right属性被声明为Optional[Tree]类型,允许为空,但to_rpn、evaluate函数要求入参必须是Tree类型。递归调用时你直接传入tree.left、tree.right,mypy无法自动识别「操作符节点必然存在左右子节点」的业务约束,因此抛出类型不兼容错误。

修复方案

方案1:添加运行时校验(推荐)

通过显式校验提前拦截非法的树结构,同时满足mypy的类型检查要求,生产环境也可以安全使用。
修改后完整代码如下:

from typing import Optional

class Tree:
    def __init__(self, value: str,
                 left: Optional['Tree'] = None,
                 right: Optional['Tree'] = None):
        self.value = value
        self.left = left
        self.right = right

def to_rpn(tree: Tree) -> str:
    if tree.value not in ("+", "*"):
        return tree.value
    # 校验操作符节点必须有左右子节点
    if tree.left is None or tree.right is None:
        raise ValueError(f"操作符节点[{tree.value}]缺少子节点,树结构非法")
    return f"{to_rpn(tree.left)} {to_rpn(tree.right)} {tree.value}"

def evaluate(tree: Tree) -> int:
    if tree.value == "+":
        if tree.left is None or tree.right is None:
            raise ValueError(f"操作符节点[{tree.value}]缺少子节点,树结构非法")
        return evaluate(tree.left) + evaluate(tree.right)
    elif tree.value == "*":
        if tree.left is None or tree.right is None:
            raise ValueError(f"操作符节点[{tree.value}]缺少子节点,树结构非法")
        return evaluate(tree.left) * evaluate(tree.right)
    else:
        return int(tree.value)

如果是开发测试场景,也可以用assert代替显式抛错,代码更简洁:

def to_rpn(tree: Tree) -> str:
    if tree.value not in ("+", "*"):
        return tree.value
    assert tree.left is not None and tree.right is not None
    return f"{to_rpn(tree.left)} {to_rpn(tree.right)} {tree.value}"

方案2:类型断言(仅适用于可100%保证树结构合法的场景)

如果你能确保所有操作符节点的左右子节点一定不为空,可以用cast直接告诉mypy类型,不需要额外运行时开销:

from typing import Optional, cast

class Tree:
    def __init__(self, value: str,
                 left: Optional['Tree'] = None,
                 right: Optional['Tree'] = None):
        self.value = value
        self.left = left
        self.right = right

def to_rpn(tree: Tree) -> str:
    if tree.value not in ("+", "*"):
        return tree.value
    left = cast(Tree, tree.left)
    right = cast(Tree, tree.right)
    return f"{to_rpn(left)} {to_rpn(right)} {tree.value}"

def evaluate(tree: Tree) -> int:
    if tree.value == "+":
        left = cast(Tree, tree.left)
        right = cast(Tree, tree.right)
        return evaluate(left) + evaluate(right)
    elif tree.value == "*":
        left = cast(Tree, tree.left)
        right = cast(Tree, tree.right)
        return evaluate(left) * evaluate(right)
    else:
        return int(tree.value)

两种方案都可以通过mypy --disallow-any-explicit --strict的检查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 00:06:03