如何解决mypy返回object类型与预期Dict/int等类型不兼容报错
问题原因
mypy推导字典类型时,会默认取所有值的公共父类作为字典的值类型。你定义的字典a的两个值分别是dict[int, int]和dict[int, int|str],二者的公共父类为object,因此mypy认为a[self.input_data]的返回类型是object,和你标注的dict[int, Any]不匹配,就会抛出对应错误。
你遇到的单行if语句问题也是同理:当mypy推导不同分支返回值的公共父类和你标注的函数返回类型不匹配时,就会抛出返回值为object类型的错误。
解决方案
方案1:给字典显式标注类型
直接给定义的字典添加类型标注,明确告知mypy字典的值类型符合预期:
from typing import Any, Dict class TestClass(): # 顺便给__init__的参数也加上类型标注可以避免额外的mypy警告 def __init__(self, input_data: str): self.input_data = input_data # always 'a' or 'b' def test(self) -> Dict[int, Any]: # 显式标注字典a的类型为 键str、值dict[int, Any] a: Dict[str, Dict[int, Any]] = {'a': {1:0, 2:0}, 'b': {2:0, 3:'string'}} return a[self.input_data]
方案2:用typing.cast强制指定返回值类型
如果不想修改原有字典的定义,可以在返回时用cast方法主动告知mypy返回值的类型:
from typing import Any, Dict, cast class TestClass(): def __init__(self, input_data: str): self.input_data = input_data # always 'a' or 'b' def test(self) -> Dict[int, Any]: a = {'a': {1:0, 2:0}, 'b': {2:0, 3:'string'}} return cast(Dict[int, Any], a[self.input_data])
方案3:单行if/三元表达式场景的处理
对于单行if语句的场景,可以通过变量显式标注或者cast处理:
from typing import cast def demo_func(flag: bool) -> int: # 错误写法:mypy可能推导返回值为公共父类object # return 1 if flag else 2 # 正确写法1:给存储结果的变量显式标注类型 res: int = 1 if flag else 2 return res # 正确写法2:直接给整个表达式加cast # return cast(int, 1 if flag else 2)
方案4:调整mypy配置(可选)
如果不需要太严格的类型检查,可以在项目的mypy.ini配置文件中添加no_implicit_any = false,避免mypy把公共父类自动推导为object,不过该方法会降低类型检查的严格性,不推荐使用。
内容的提问来源于stack exchange,提问作者dmmpie
相关产品推荐
相关产品推荐

