半单例类实例存储字典的Python严格类型注解方法问询
半单例类实例存储字典的严格类型注解方案
核心思路
通过绑定到Foo及其子类的TypeVar配合Generic,让类型检查器能精准跟踪每个子类对应的实例类型,既解决TypeVar未绑定的错误,又避免不同子类实例混存的类型不安全问题。
完整实现代码
from typing import TypeVar, Generic, Type, ClassVar, Dict # 绑定到Foo及其子类的类型变量,解决未绑定错误 FooSubtype = TypeVar("FooSubtype", bound="Foo") class Foo(Generic[FooSubtype]): # 类级实例存储字典:键为(子类类型, slug),值为对应子类的实例 _instances: ClassVar[Dict[tuple[Type[FooSubtype], str], FooSubtype]] = {} def __new__(cls: Type[FooSubtype], slug: str) -> FooSubtype: key = (cls, slug) if key not in cls._instances: instance = super().__new__(cls) instance.slug = slug # 实例初始化逻辑示例 cls._instances[key] = instance return cls._instances[key] # 子类示例 class Bar(Foo["Bar"]): pass
类型安全验证
- 调用
Foo("a_slug")返回Foo类型实例,重复调用返回同一实例 - 调用
Bar("a_slug")返回Bar类型实例,与Foo("a_slug")完全独立 - 类型检查器会拦截错误操作,比如将
Bar实例赋值给非Foo/Bar类型变量,或错误取出不属于当前子类的实例
关键注解说明
FooSubtype = TypeVar("FooSubtype", bound="Foo"):把类型变量限定为Foo及其子类,明确合法范围,解决“Type variable is unbound”错误ClassVar[Dict[tuple[Type[FooSubtype], str], FooSubtype]]:标注_instances是类级变量,同时强制字典键值对类型匹配——键中的类类型必须对应值的实例类型__new__方法的cls: Type[FooSubtype]和返回值FooSubtype:确保创建/返回的实例类型与调用的类严格一致
内容的提问来源于stack exchange,提问作者Vedran Šego
相关产品推荐
相关产品推荐

