You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为类到实例映射的字典添加类型提示?含单例元类场景

为类型-实例字典添加正确的类型提示

基础场景:单个字典的类型标注

直接使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:08:31