Mypy类型问题:为何标注Dict[str,Dict[str,str]]会触发重载匹配错误?
为什么Mypy在不同Dict标注下对
get调用报错? 咱们一步步拆解这个问题,核心原因和Mypy的类型推断规则以及泛型Dict的类型约束直接相关:
先看报错的两种情况(示例1和示例2)
- 示例1里你给
scheme标注了明确的泛型类型Dict[str, Dict[str, str]],示例2没加标注,但Mypy会自动推断scheme的类型也是Dict[str, Dict[str, str]]——这个类型意味着scheme的键必须是字符串类型,对应的值是嵌套的字典。 - 再看
payload的类型变化:你先把它赋值为字典{'flag': 'good'},Mypy会推断它的初始类型是Dict[str, str];接着你把它重新赋值为payload['flag'](也就是字符串'good')。因为没给payload加明确的类型标注,Mypy会把payload的类型推断为所有赋值类型的联合,也就是Union[Dict[str, str], str](既可能是字典,也可能是字符串)。 - 当你调用
scheme.get(payload)时,scheme的get方法只接受字符串类型的键,但payload存在是字典的可能性,这就违反了泛型Dict的类型约束,所以Mypy抛出错误:No overload variant of "get" of "Mapping" matches argument type "Dict[str, Any]"。
再看不报错的情况
当你把scheme标注为Dict(不带泛型参数)时,Mypy会把它视为Dict[Any, Any]——这种情况下,scheme的get方法接受任意类型的参数,payload的Union[Dict[str, str], str]类型自然符合要求,所以不会触发类型检查错误。
小建议:兼顾类型安全和检查通过
如果想让代码既符合类型安全规范,又能顺利通过Mypy检查,最好给payload加上明确的字符串类型标注:
payload = { 'flag': 'good' } payload: str = payload['flag'] # 明确标注payload为字符串类型 scheme: Dict[str, Dict[str, str]] = { 'a_string': { 'status': 'abc_string' } } scheme.get(payload).get('status')
这样Mypy就明确知道payload肯定是字符串类型,不会再抛出类型不匹配的错误。
内容的提问来源于stack exchange,提问作者apollowebdesigns
相关产品推荐
相关产品推荐

