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

如何为存储子类与对应处理函数的字典f添加正确类型注解?

解决字典类型提示不兼容的问题

情况1:子类固定(仅A、B)

如果你的子类范围确定只有A和B,用TypedDict是最直接的方案,能精准约束每个键对应的函数类型:

from typing import TypedDict, Callable, Type

class Sup:
    pass

class A(Sup):
    pass

class B(Sup):
    pass

def get_A_report(a: A) -> int:
    return 1

def get_B_report(b: B) -> int:
    return 2

# 定义TypedDict,明确每个类键对应的函数签名
class ReportMap(TypedDict):
    A: Callable[[A], int]
    B: Callable[[B], int]

# 给字典f添加类型提示
f: ReportMap = {A: get_A_report, B: get_B_report}

情况2:需要支持任意Sup子类(通用场景)

如果后续可能新增Sup的子类,用带逆变约束的TypeVar结合Mapping实现通用类型兼容:

from typing import TypeVar, Mapping, Callable, Type

class Sup:
    pass

class A(Sup):
    pass

class B(Sup):
    pass

# 定义绑定到Sup的逆变TypeVar,解决类型协变/逆变不兼容问题
T = TypeVar('T', bound=Sup, contravariant=True)

def get_A_report(a: A) -> int:
    return 1

def get_B_report(b: B) -> int:
    return 2

# 用Mapping而非Dict(Dict是不变类型,无法利用协变/逆变规则)
f: Mapping[Type[T], Callable[[T], int]] = {A: get_A_report, B: get_B_report}

为什么之前的写法报错?

你之前用Dict[Type[Sup], Callable[[Sup], int]]时,get_A_report的签名是Callable[[A], int],它并不等同于Callable[[Sup], int]——因为get_A_report只能接受A实例,无法处理任意Sup子类(比如B实例),所以类型检查器会判定不兼容。而用逆变TypeVar+Mapping的方式,能让类型检查器识别出:每个键对应的函数仅需接受该键类的实例即可,符合逆变的类型规则。

内容的提问来源于stack exchange,提问作者Vince

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:49:59