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

Python运行时获取任意层级泛型父类类型参数的方案咨询

鲁棒实现方案

核心思路是遍历继承链的同时维护类型变量到实际值的映射表,逐层替换泛型参数,最终得到目标父类的实际类型参数:

import typing
from dataclasses import dataclass
from typing import Optional, Any, TypeVar, Generic, get_origin, get_args

T = TypeVar('T')

@dataclass(frozen=True)
class Found:
    value: Any

def get_generic_parent_args(target_parent: type, cls: Any) -> Optional[Found]:
    # 处理参数化泛型输入,比如Child3[int]的情况
    type_map = {}
    current_cls = cls
    origin_cls = get_origin(cls)
    if origin_cls is not None:
        # 提取最外层的泛型参数绑定
        type_params = origin_cls.__parameters__
        type_args = get_args(cls)
        type_map = {param: arg for param, arg in zip(type_params, type_args)}
        current_cls = origin_cls

    # 遍历MRO继承链
    for base in current_cls.mro():
        if base == target_parent:
            break
        # 遍历当前类的原始泛型基类
        for orig_base in getattr(base, "__orig_bases__", ()):
            base_origin = get_origin(orig_base)
            if base_origin is None:
                continue
            
            # 替换当前基类参数中的类型变量
            def replace_type_vars(t: Any) -> Any:
                if isinstance(t, TypeVar):
                    return type_map.get(t, t)
                args = get_args(t)
                if not args:
                    return t
                replaced_args = tuple(replace_type_vars(arg) for arg in args)
                return get_origin(t)[replaced_args]
            
            replaced_base_args = tuple(replace_type_vars(arg) for arg in get_args(orig_base))

            # 找到目标父类,返回替换后的参数
            if base_origin is target_parent:
                return Found(replaced_base_args[0] if len(replaced_base_args) == 1 else replaced_base_args)
            
            # 基类是泛型类,更新类型映射表,继续向下遍历
            if hasattr(base_origin, "__parameters__"):
                for param, arg in zip(base_origin.__parameters__, replaced_base_args):
                    type_map[param] = arg
    
    return None

测试验证

可直接覆盖所有需求场景:

# 基础定义
class Parent(Generic[T]):
    pass

# 多层继承场景
class Child1(Parent[int]):
    pass
class Child2(Child1):
    pass
print(get_generic_parent_args(Parent, Child2)) # Found(value=<class 'int'>)

# 泛型子类场景
class Child3(Parent[T], Generic[T]):
    pass
print(get_generic_parent_args(Parent, Child3[int])) # Found(value=<class 'int'>)

# 嵌套泛型场景
from typing import Sequence
class Child4(Parent[Sequence[T]], Generic[T]):
    pass
print(get_generic_parent_args(Parent, Child4[int])) # Found(value=typing.Sequence[int])

# OpenAPI业务场景
from dataclasses import dataclass
from typing import ClassVar, Union

@dataclass
class Data:
    hello: str
@dataclass
class Error:
    detail: str

class ClientResponse(Generic[T]):
    status_code: ClassVar[int]
    body: T

class OkResponse(ClientResponse[Data]):
    status_code: ClassVar[int] = 200
class BadResponse(ClientResponse[Error]):
    status_code: ClassVar[int] = 400

print(get_generic_parent_args(ClientResponse, OkResponse)) # Found(value=<class '__main__.Data'>)
print(get_generic_parent_args(ClientResponse, BadResponse)) # Found(value=<class '__main__.Error'>)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:12:01