如何为Python中泛型类型到实例的映射方法正确添加类型提示?
问题
现有如下继承结构:
class S: ... class A(S): ... class B(S): ...
我想实现一个封装字典的类Foo,字典的键是S的子类类型(比如A、B),值是对应子类的实例(比如A()、B())。我尝试写了如下代码,但希望静态分析工具能识别get方法返回的是输入类型的具体实例,而不是仅父类S的实例:
class Foo: T = TypeVar('T', bound=S) items: dict[type[T], T] = dict() def get(self, t: type[T]) -> T: return self.items[t]
请问该如何正确编写类型提示?
解决方案
你原来的写法存在问题:类级别的TypeVar无法在实例层面动态关联字典键和值的类型。下面是两种正确的实现方式:
方式一:基于方法级TypeVar
from typing import TypeVar, Type class S: ... class A(S): ... class B(S): ... # 定义绑定到S的TypeVar,作用域覆盖方法 T = TypeVar('T', bound=S) class Foo: # 字典基础类型标注为S子类类型到S实例的映射 items: dict[type[S], S] = {} def get(self, t: type[T]) -> T: # 类型断言告知静态分析工具返回值的具体类型 return self.items[t] # type: ignore
方式二:用Generic约束类
from typing import TypeVar, Generic, Type class S: ... class A(S): ... class B(S): ... T = TypeVar('T', bound=S) # 用Generic约束类,让类和TypeVar关联 class Foo(Generic[T]): items: dict[type[S], S] = {} def get(self, t: Type[T]) -> T: return self.items[t] # type: ignore
关键说明
- 字典的基础类型标注为
dict[type[S], S],因为它存储的是所有S子类的类型与对应实例的映射。 get方法中的type[T]会让静态分析工具将输入的子类类型(比如A)和返回值的实例类型(A的实例)绑定,这样调用foo.get(A)时,工具能识别返回的是A实例而非S实例。# type: ignore是必要的:静态分析工具无法自动确认字典中存在对应类型的实例,需要开发者保证业务逻辑的正确性。
如果使用Python 3.10及以上版本,可省略Type导入,直接用type[T]写法,和示例一致。
内容的提问来源于stack exchange,提问作者bossi
相关产品推荐
相关产品推荐

