如何为类到实例映射的字典添加类型提示?含单例元类场景
为类型-实例字典添加正确的类型提示
基础场景:单个字典的类型标注
直接使用dict[type[T], T]会报错,原因是TypeVar必须绑定到泛型上下文(比如泛型函数、类或别名)。要标注存储“类型-对应实例”的字典,正确方式是通过泛型别名明确键值的对应关系:
from typing import TypeVar, Dict # 定义可表示任意类型的TypeVar T = TypeVar("T") # 创建泛型别名,明确键为类型、值为对应实例 TypeInstanceMap = Dict[type[T], T] class Demo: pass foo: TypeInstanceMap = { int: 5, str: "Hi", Demo: Demo() }
如果你的类型检查器仍有兼容性提示,也可以使用更宽泛但能通过检查的写法:
from typing import Dict, Type foo: Dict[Type, object] = { int: 5, str: "Hi", Demo: Demo() }
第一种写法能更精确地约束键值类型对应关系,优先推荐。
进阶场景:单例元类的类型标注
针对你的单例元类,核心是在方法中绑定cls的类型,让TypeVar关联到具体类及其实例类型,这样类型检查器就能正确推断_instances字典和方法返回值的类型:
from typing import ClassVar, TypeVar, Dict, Type # 定义TypeVar表示任意类的实例类型 T = TypeVar("T") class Singleton(type): # _instances为类变量,键是任意类型,值是对应类型的实例 _instances: ClassVar[Dict[Type[T], T]] = {} def __call__(cls: Type[T], *args, **kwargs) -> T: instance = cls._instances.get(cls) if instance is None: instance = cls._instances[cls] = super().__call__(*args, **kwargs) return instance name = cls.__name__ raise RuntimeError( f"{name} already created. use {name}.get() to get the {name} instance." ) def get(cls: Type[T]) -> T | None: return cls._instances.get(cls)
关键细节:
- 在
__call__和get方法中,通过cls: Type[T]将当前类绑定到Type[T],让T自动对应该类的实例类型,类型检查器就能正确识别方法返回值的类型。 - 用
ClassVar标注_instances,明确它是元类的类变量,而非实例变量。
内容的提问来源于stack exchange,提问作者Shai Avr
相关产品推荐
相关产品推荐

