Mypy类型错误:字典索引类型不匹配(str与Literal类型不兼容)
Mypy类型错误:字典索引类型不匹配(str与Literal类型不兼容)
嘿,我完全懂你碰到的这个问题——Mypy在类型检查上特别较真,你给字典objects_dict定义了Literal类型的键,但clazz.__name__返回的是普通的str,这俩类型没法直接匹配,所以就报错了。结合你的代码场景,给你几个实用的解决办法:
方法一:用类型断言直接告诉Mypy你的意图
如果你能确定inspect.getmembers返回的所有类名称都正好在你定义的objectNames列表里,那可以用cast来做类型断言,让Mypy相信这个字符串就是合法的Literal键:
from typing import cast import inspect import objects # 你的类型定义不变 objectNames = Literal[ 'TranslatableHtml', 'TranslatableUnicodeString', 'TranslatableSetOfUnicodeString', 'TranslatableSetOfNormalizedString', ] objectClasses = Union[ Type[objects.TranslatableHtml], Type[objects.TranslatableUnicodeString], Type[objects.TranslatableSetOfUnicodeString], Type[objects.TranslatableSetOfNormalizedString], ] objects_dict: Dict[objectNames, objectClasses] = {} # 修改后的赋值代码 for name, clazz in inspect.getmembers(objects): # 断言name属于objectNames类型 typed_name = cast(objectNames, name) objects_dict[typed_name] = clazz
注意:这个方法的前提是你100%确认遍历到的类名称都在
objectNames里,不然运行时可能会出现意外的键值对,破坏类型约束。
方法二:用类型守卫做安全校验(更推荐)
如果想兼顾类型安全和Mypy的检查,可以写一个类型守卫函数,同时验证类名称和类的类型,只有符合条件的才赋值给字典:
from typing import Literal, Union, Dict, Type, TypeGuard import inspect import objects objectNames = Literal[ 'TranslatableHtml', 'TranslatableUnicodeString', 'TranslatableSetOfUnicodeString', 'TranslatableSetOfNormalizedString', ] objectClasses = Union[ Type[objects.TranslatableHtml], Type[objects.TranslatableUnicodeString], Type[objects.TranslatableSetOfUnicodeString], Type[objects.TranslatableSetOfNormalizedString], ] objects_dict: Dict[objectNames, objectClasses] = {} # 定义类型守卫函数 def is_valid_translatable(name: str, clazz: object) -> TypeGuard[tuple[objectNames, objectClasses]]: # 检查名称是否在Literal的取值范围内,同时类是否属于目标类型 return name in objectNames.__args__ and isinstance(clazz, tuple(objectClasses.__args__)) for name, clazz in inspect.getmembers(objects): if is_valid_translatable(name, clazz): # 经过守卫校验后,Mypy能识别name是objectNames类型 objects_dict[name] = clazz
这个方法更稳妥,既过滤了不需要的类成员,又让Mypy能正确推断类型,避免了潜在的运行时错误。
方法三:放宽字典键的类型(不推荐,除非必要)
如果你的场景不需要严格限制字典键的取值,也可以把字典的键类型从objectNames改成普通的str,这样Mypy就不会报错了:
objects_dict: Dict[str, objectClasses] = {}
不过这样就失去了Literal类型带来的严格类型检查,没法防止意外插入不符合要求的键,所以只适合对类型约束要求不高的场景。
备注:内容来源于stack exchange,提问作者Sujay
相关产品推荐
相关产品推荐

