为何TypeVar比Union的mypy错误检测更精准?附报错解析
Union与TypeVar实现max函数的类型检查差异解析
两种实现代码
基于Union的版本
from typing import Union U = Union[int, str] def max_1(var1: U, var2: U) -> U: return max(var1, var2) print(max_1("foo", 1)) # mypy 不报错,哪怕参数一个是str一个是int print(max_1(1, "foo")) print(max_1(1, 2)) print(max_1("foo", "bar"))
基于TypeVar的版本
from typing import TypeVar T = TypeVar("T", int, str) def max_2(var1: T, var2: T) -> T: return max(var1, var2) print(max_2("foo", 1)) # mypy 此处报错 print(max_2(1, "foo")) print(max_2(1, 2)) print(max_2("foo", "bar"))
mypy的检测逻辑差异
Union的检查逻辑
Union[int, str]的核心规则是:每个参数只要是int或者str就行,两个参数不需要是同一种类型。所以你传一个str和一个int时,mypy会判定每个参数都符合U的类型要求,自然不会触发错误。
TypeVar的检查逻辑
这里定义的T是带约束的类型变量,它要求函数的两个参数必须是同一种具体类型——要么全是int,要么全是str。当你传入str和int时,mypy会尝试寻找一个能同时覆盖这两个参数的类型,但int和str的共同父类型是object,而object不在我们给T指定的约束范围(int、str)内,因此触发错误。
报错中"object"的含义
Python里所有类型最终都继承自object,当mypy找不到符合T约束范围的共同类型时,会退而求其次找到它们最顶层的共同父类型object。但因为我们明确限定T只能是int或str,object不在允许的类型列表里,所以mypy报错提示“类型变量T无法解析为object”——本质是在说:找不到一个属于[int, str]集合里的类型,能同时匹配你传入的str和int参数。
内容的提问来源于stack exchange,提问作者Magaren
相关产品推荐
相关产品推荐

