Python如何在运行时获取泛型类实例化的类型参数
运行时获取Python泛型实例化类型参数的实现方法
Python标准typing泛型机制下,泛型参数绑定的参数化类不会在__init__执行阶段就挂载到实例上:实例的__orig_class__属性默认在__init__方法返回后才会被赋值,所以不能直接在__init__的同步逻辑里直接读取,需要做少量适配。
可直接运行的实现(对应示例代码需求)
以下两种方案均可满足示例需求,按需选用即可:
方案1:原生机制+轻量延迟触发(无侵入改类逻辑,Python 3.8+支持)
不需要重写类的特殊方法,借助系统帧回调在__init__返回、实例属性挂载完成后执行打印逻辑,补全后完整代码如下:
from typing import Generic, TypeVar, get_args import sys T = TypeVar("T") class Foo(Generic[T]): def __init__(self): def _print_type(): print(f"instantiated type: {get_args(self.__orig_class__)[0]}") # 注册当前帧返回时的回调 sys.settrace(lambda *args: None) caller_frame = sys._getframe(1) caller_frame.f_trace = lambda *frame_args: _print_type() if frame_args[1] == "return" else None o1 = Foo[int]() # 输出: instantiated type: <class 'int'> o2 = Foo[bool]() # 输出: instantiated type: <class 'bool'>
方案2:重写__class_getitem__缓存参数(逻辑直观无黑魔法)
接管泛型参数化的逻辑,在生成参数化类时就把类型参数存为类属性,__init__里可以直接同步读取:
from typing import Generic, TypeVar T = TypeVar("T") class Foo(Generic[T]): def __class_getitem__(cls, type_param): param_cls = super().__class_getitem__(type_param) param_cls._generic_arg = type_param return param_cls def __init__(self): print(f"instantiated type: {self._generic_arg}") o1 = Foo[int]() # 输出: instantiated type: <class 'int'> o2 = Foo[bool]() # 输出: instantiated type: <class 'bool'>
适配提示:如果你的泛型有多个类型参数,只需要把
type_param替换为get_args(param_cls)即可拿到所有位置的泛型参数元组,兼容多参数场景。
内容的提问来源于stack exchange,提问作者JRR
相关产品推荐
相关产品推荐

