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

如何从自定义类型提示CustomParameter中获取泛型参数Sunshine?

问题描述

我写了一个简单的泛型类CustomParameter:

from typing import TypeVar, Generic
T = TypeVar('T')
class CustomParameter(Generic[T]):
    def __init__(self, value: T) -> None:
        print(value, T)
        self.value = value
    def get(self) -> T:
        print(self.value)
        return self.value

之后在函数的类型注解里用了带字符串类型参数的泛型:

def is_dark(x: CustomParameter['Sunshine']) -> int:
    return x

现在我想从CustomParameter['Sunshine']这个类型注解里提取出'Sunshine'对应的实际类型,用来检查输入x的value是不是真的Sunshine类型的对象,请问该怎么实现?

解决方案

要提取泛型类型注解里的类型参数,你可以用Python标准库的typing.get_args()、typing.get_origin(),再结合inspect模块来解析函数的参数注解。下面是具体的实现步骤和代码:

步骤1:获取函数的参数注解

先用inspect.signature()拿到目标函数的签名,然后就能取出对应参数的类型注解。

步骤2:解析泛型类型

用get_origin()确认注解是CustomParameter的泛型实例,再用get_args()提取里面的类型参数(也就是你写的'Sunshine')。

步骤3:映射到实际类型

因为你用的是字符串形式的类型名,需要把它转换成当前作用域里的实际类对象。

完整的示例代码如下:

import inspect
from typing import get_args, get_origin
from typing import TypeVar, Generic

T = TypeVar('T')
class CustomParameter(Generic[T]):
    def __init__(self, value: T) -> None:
        print(value, T)
        self.value = value
    def get(self) -> T:
        print(self.value)
        return self.value

# 先定义你的Sunshine类(假设这是你实际要用的类型)
class Sunshine:
    pass

def is_dark(x: CustomParameter['Sunshine']) -> int:
    return x

# 封装一个提取泛型参数的工具函数
def extract_generic_type(func, param_name):
    # 获取函数的签名信息
    sig = inspect.signature(func)
    # 拿到目标参数的类型注解
    param_anno = sig.parameters[param_name].annotation
    
    # 先确认这个注解是CustomParameter的泛型实例
    if get_origin(param_anno) is CustomParameter:
        # 提取泛型的类型参数,得到('Sunshine',)这样的元组
        generic_args = get_args(param_anno)
        # 取出第一个参数(因为我们的泛型只有一个类型变量T)
        type_str = generic_args[0]
        # 从全局作用域中获取对应的实际类型
        actual_type = globals().get(type_str)
        return actual_type
    return None

# 测试一下提取结果
target_type = extract_generic_type(is_dark, 'x')
print(target_type)  # 会输出 <class '__main__.Sunshine'>

# 现在就可以用这个类型来检查输入了
test_param = CustomParameter(Sunshine())
if isinstance(test_param.get(), target_type):
    print("输入的value确实是Sunshine类型的对象")
else:
    print("输入的value不是Sunshine类型")

几个关键点说明:

  • get_origin():这个函数会返回泛型的原始类,比如这里的CustomParameter,用来确保我们处理的是正确的泛型类型,避免误解析其他注解。
  • get_args():返回泛型的类型参数元组,这里因为我们的泛型只有一个类型变量T,所以取第一个元素就好。
  • globals().get(type_str):如果你的Sunshine类在其他模块里,那你需要换成从对应模块的__dict__里获取,或者用importlib来动态导入,确保能拿到实际的类对象。

另外要注意,这个方案是针对运行时提取类型参数的,如果是在静态类型检查阶段(比如用mypy),处理逻辑会不一样,但日常运行时的类型校验需求,这个方法完全够用。

内容的提问来源于stack exchange,提问作者code base 5000

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:01:40