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

如何消除mypy对泛型继承检测的报错?

解决泛型实例类型映射的mypy报错问题

代码修正方案

要让mypy认可你的代码,需要用Protocol描述泛型实例特有的属性(__orig_bases__和__orig_class__),同时替换无效的isinstance(obj, Generic)检查:

from typing import Generic, TypeVar, get_args, Protocol, runtime_checkable

T = TypeVar("T")


class Derived(Generic[T]):
    def method(self, val: T) -> T:
        return val


d = Derived[int]()

# 定义运行时可检查的Protocol,描述泛型实例的属性
@runtime_checkable
class GenericInstance(Protocol):
    __orig_bases__: tuple
    __orig_class__: type


def get_generic_types_mapping(obj: object) -> dict[type, type]:
    if isinstance(obj, GenericInstance):
        # 提取带类型参数的泛型基类
        generic_base = next(
            origin
            for origin in obj.__orig_bases__
            if hasattr(origin, "__origin__") and origin.__origin__ is Generic
        )
        # 映射TypeVar到实际类型
        return dict(zip(get_args(generic_base), get_args(obj.__orig_class__)))
    else:
        return {}


assert get_generic_types_mapping(d) == {T: int}
assert get_generic_types_mapping(object()) == {}

关键概念解释

  1. 为什么isinstance(obj, Generic)无效?
    Generic是typing模块中的特殊构造,仅用于标记类为泛型,本身不是可实例化的普通类,因此不能作为isinstance的第二个参数做类型检查。

  2. __orig_bases__和__orig_class__的来源
    这两个属性是Python typing模块在处理泛型类实例化(比如Derived[int]())时自动添加的实现细节:

  • __orig_class__:指向实例化时的具体泛型类(比如Derived[int]),包含已绑定的类型参数。
  • __orig_bases__:存储类的原始基类元组,其中包含带类型参数的Generic基类(比如Generic[int])。
    它们不属于Python官方公开API,但运行时可以稳定访问。
  1. 处理未指定类型参数的泛型实例
    如果希望对Derived()这种未绑定类型参数的实例抛出错误,可在函数中添加额外检查:
def get_generic_types_mapping(obj: object) -> dict[type, type]:
    if isinstance(obj, GenericInstance):
        # 现有逻辑...
    elif issubclass(type(obj), Generic):
        raise ValueError("该泛型实例未指定类型参数")
    else:
        return {}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:25:17