如何用Python Mypy为返回不同数量值的函数添加类型注解?
解决不同长度元组返回值的类型注解问题
直接用Union[Tuple[int, bool], Tuple[int, str, float]]确实会让Mypy在解包时困惑——它没法确定当前返回的是哪一种元组,所以会抛出解包数量不匹配的错误。这里有两种可行的解决方案:
方案1:用函数重载+字面量类型(适用于输入是固定枚举值的场景)
如果你的函数输入x是有限的几个固定字符串(比如"mode1"、"mode2"),可以用@overload结合Literal来精确标注不同输入对应的返回类型,让Mypy能精准推断:
from typing import overload, Literal, Tuple @overload def func(x: Literal["mode1"]) -> Tuple[int, bool]: ... @overload def func(x: Literal["mode2"]) -> Tuple[int, str, float]: ... def func(x: str): if x == "mode1": return (1, True) elif x == "mode2": return (2, "hello", 3.14) else: raise ValueError("Invalid mode") # 此时Mypy能正确推断,解包无报错 a, b = func("mode1") c, d, e = func("mode2")
方案2:解包前做类型窄化(适用于输入动态的场景)
如果输入x是动态的,没法用字面量限定,那需要在解包前通过类型检查缩小返回值的类型范围,让Mypy明确当前处理的是哪种元组:
from typing import Union, Tuple def func(x: str) -> Union[Tuple[int, bool], Tuple[int, str, float]]: if x.startswith("bool"): return (1, True) else: return (2, "test", 4.5) result = func("some_input") # 通过长度检查做类型窄化 if len(result) == 2: num, flag = result # Mypy知道这里是Tuple[int, bool] elif len(result) == 3: num, text, val = result # Mypy知道这里是Tuple[int, str, float] else: raise ValueError("Unexpected return format")
这样处理后,Mypy就能正确识别不同分支下的元组类型,不会再抛出解包错误。
内容的提问来源于stack exchange,提问作者baxx
相关产品推荐
相关产品推荐

