使用mypy检查含dict.get的代码时类型报错,求标准解决方法
问题
我编写了如下代码:
di: dict[str, float] max_val = max(di, key=di.get)
运行mypy进行类型检查时,出现如下报错:
error: Argument "key" to "max" has incompatible type overloaded function; expected "Callable[[str], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]"
我推测原因在于:通常dict.get的返回类型是Union[float, None],但在此场景中,该方法仅会被传入字典di中的键,因此返回值必然是float。我已找到三种临时解决方法:自定义lambda函数、忽略类型检查报错、使用cast强制类型转换,具体代码如下:
# 方法1:自定义lambda函数 get_lambda = lambda key: di[key] max_val = max(di, key=get_lambda) # --------- # 方法2:忽略类型检查报错 max_val = max( di, key=di.get, # type: ignore [arg-type] ) # --------- # 方法3:使用cast强制类型转换 from typing import cast, Callable max_val = max(di, key=cast(Callable[[str], float], di.get))
请问是否存在更规范、标准的方式,让mypy知晓该场景下dict.get不会返回None?
规范解决方案
方案1:使用字典索引访问替代dict.get
直接用di[key]替代di.get(key)是最直观且类型安全的方案——因为遍历字典的键时,所有传入的键必然存在于字典中,索引访问不会返回None,mypy能自动推导其返回类型为float。可以简化成紧凑的lambda写法:
di: dict[str, float] max_val = max(di, key=lambda k: di[k])
方案2:遍历items()结合operator.itemgetter
如果想避免lambda,可借助operator.itemgetter直接提取值进行比较,这种写法符合Python惯用风格,且mypy能正确识别类型:
from operator import itemgetter di: dict[str, float] max_val = max(di.items(), key=itemgetter(1))[0]
不推荐的方案说明
# type: ignore会跳过类型检查,可能隐藏后续代码的潜在类型问题,不建议在可避免的场景使用。cast需要手动断言类型,增加了维护成本,且不如索引访问或items()写法直观。
内容的提问来源于stack exchange,提问作者natty
相关产品推荐
相关产品推荐

