Python 如何使用装饰器获取类泛型类型的运行时类型?
我有一个泛型类,比如Python 如何使用装饰器获取类泛型类型的运行时类型?,python,python-3.x,generics,annotations,typing,Python,Python 3.x,Generics,Annotations,Typing,我有一个泛型类,比如 从输入import Generic、TypeVar、List T=TypeVar('T') @我的装饰师 类Foo(泛型[T]): 通过 f:Foo[int]=Foo() g:Foo[List[float]]=Foo() 有没有一种干净的方法可以在decorator中获取构造函数调用的类型注释Foo[int],Foo[List[float]]?我想在运行时做一些类型检查 我可以通过decorator访问Foo的构造函数调用,甚至可以通过使用inspect.stack()和
从输入import Generic、TypeVar、List
T=TypeVar('T')
@我的装饰师
类Foo(泛型[T]):
通过
f:Foo[int]=Foo()
g:Foo[List[float]]=Foo()
有没有一种干净的方法可以在decorator中获取构造函数调用的类型注释Foo[int],Foo[List[float]]
?我想在运行时做一些类型检查
我可以通过decorator访问Foo
的构造函数调用,甚至可以通过使用inspect.stack()
和inspect.getsource(我的框架)
以非常不寻常的方式获得构造函数调用的代码行f:Foo[int]=Foo()
。然后我可以通过一些字符串操作获得Foo[int]
除此之外,这是一种非常肮脏的方法,它只获取字符串形式的类型。但我需要真正的类型。在本例中,我可以使用eval()
来“解析”字符串并将其转换为类型。但这不适用于自定义类,如本例中所示:
从输入import Generic、TypeVar、List
T=TypeVar('T')
分类栏:
通过
@我的装饰师
类Foo(泛型[T]):
通过
h:Foo[List[Bar]]=Foo()
在这种情况下,我不能使用eval()
,因为我不知道如何获得正确的上下文。
我喜欢得到类似于my_file.Foo[typing.List[my_file.Bar]
的东西,它允许我在运行时进行类型检查
那么有没有干净的方法呢?或者是否至少有一种(肮脏的)方法来获取正确的上下文,以便eval()
来“解析”字符串?TL;DR:这不可能在\uuuu init\uuuu>中获得泛型的运行时类型,但我们可以在CPython实现中获得足够的接近度
要在类中仅使用decorator处理此问题,您应该将调用更改为h=Foo[List[Bar]]()
,以便decorator可以独立于保存返回对象的变量访问typehint
指示泛型类的类实例在初始化后具有可用的\uuuuu orig\u class\uuuuu
属性。此属性在init之后设置(请参阅)
因此,如果我们编写一个类装饰器,装饰器应该修改源类,以便在运行时设置\uuuu orig\u class\uuuu
属性时基本侦听。不过,这在很大程度上依赖于未记录的实现细节,在Python的未来版本或其他实现中可能不会以同样的方式工作
def my_decorator(cls):
原始基准=cls.\uu原始基准__
genericType=原始基[0]
类别cls2(cls,genericType):
定义初始化(self,*args,**kwargs):
超级(cls2,自我)。\uuuuuuuuuuuuuuuuuu初始(*args,*kwargs)
定义设置属性(自身、名称、值):
对象。设置属性(自身、名称、值)
如果名称=“\uuuuu原始类”:
打印(“运行时泛型类型为”+str(获取参数(self.\uuu orig\u类)))
cls2.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu基
返回cls2
然后:
h=Foo[List[Bar]]()
运行时泛型类型为(typing.List[\uuuu main\uuuu.Bar],)
相关:。您能提供my_decorator
的示例代码吗?现在还不清楚你想要实现什么。