传递父类与子类作为变量时的Mypy类型不兼容问题求解
解决Mypy类型不兼容问题的几种方案
方案一:类型断言快速解决
直接用cast明确告知Mypy当前typ的具体子类类型,适合简单场景快速修复:
from typing import cast class Parent: some_attr: str class Child1(Parent): some_attr = 'foo' class Child2(Parent): some_attr = 'bar' lookup_dict: dict[str, type[Parent]] = { 'child1': Child1, 'child2': Child2, } def child1_function(typ: type[Child1]) -> None: ... def child2_function(typ: type[Child2]) -> None: ... def parent_function(key: str) -> None: typ = lookup_dict[key] if typ.some_attr == 'foo': child1_function(cast(type[Child1], typ)) if typ.some_attr == 'bar': child2_function(cast(type[Child2], typ))
方案二:类型对象判断+精确字典类型
放弃依赖some_attr判断,直接对比类型对象本身,同时给字典添加更精确的类型标注,让Mypy自动完成类型推断:
from typing import Literal, Union class Parent: some_attr: str class Child1(Parent): some_attr = 'foo' class Child2(Parent): some_attr = 'bar' # 明确限定字典的键和对应值的类型 lookup_dict: dict[Literal['child1', 'child2'], Union[type[Child1], type[Child2]]] = { 'child1': Child1, 'child2': Child2, } def child1_function(typ: type[Child1]) -> None: ... def child2_function(typ: type[Child2]) -> None: ... def parent_function(key: str) -> None: typ = lookup_dict[key] if typ is Child1: child1_function(typ) elif typ is Child2: child2_function(typ)
方案三:用TypedDict绑定键与子类类型(可扩展)
通过TypedDict定义每个键对应的子类类型,结合字面量类型限制入参键,让类型系统更严谨,适合后续需要扩展更多子类的场景:
from typing import Literal, TypedDict class Parent: some_attr: str class Child1(Parent): some_attr = 'foo' class Child2(Parent): some_attr = 'bar' # 定义字典的键值类型映射规则 class LookupDict(TypedDict): child1: type[Child1] child2: type[Child2] lookup_dict: LookupDict = { 'child1': Child1, 'child2': Child2, } def child1_function(typ: type[Child1]) -> None: ... def child2_function(typ: type[Child2]) -> None: ... # 限制入参key为字典的可选键字面量 def parent_function(key: Literal['child1', 'child2']) -> None: typ = lookup_dict[key] if key == 'child1': child1_function(typ) elif key == 'child2': child2_function(typ)
关于之前泛型尝试失败的原因
单独将lookup_dict标注为dict[str, type[PT]]时,PT作为未绑定的TypeVar,Mypy无法确定它对应哪个具体子类。泛型需要在函数或类的上下文环境中被绑定使用,而非直接用于字典的类型标注。
内容的提问来源于stack exchange,提问作者jackt247
相关产品推荐
相关产品推荐

