Python 如何获取泛型[T]子类成员变量的实际声明类型
我试图得到泛型变量的真实类型。我尝试了很多方法,但是没有一种看起来有希望 下面是演示我的问题的最基本的代码:Python 如何获取泛型[T]子类成员变量的实际声明类型,python,python-3.x,typing,Python,Python 3.x,Typing,我试图得到泛型变量的真实类型。我尝试了很多方法,但是没有一种看起来有希望 下面是演示我的问题的最基本的代码: 从输入导入* T=TypeVar('T') G类(一般[T]): x:T=无 类R(G[int]): 通过 我想在运行时获得R.x的真实类型。我的第一次尝试是使用get\u-type\u-hints。它给 {'x':~T} 看起来不是很有用 我还尝试了R.\uuuuu orig\u base\uuuuu。它确实有一些东西: (\uuuu main\uuuu.G[int],) 但将基
从输入导入*
T=TypeVar('T')
G类(一般[T]):
x:T=无
类R(G[int]):
通过
我想在运行时获得R.x
的真实类型。我的第一次尝试是使用get\u-type\u-hints
。它给
{'x':~T}
看起来不是很有用
我还尝试了R.\uuuuu orig\u base\uuuuu
。它确实有一些东西:
(\uuuu main\uuuu.G[int],)
但将基类类型参数与成员变量对齐太复杂了
你们有没有办法在运行时获得真正类型的
R.x
?有可能吗?好吧,考虑到R
专门继承G[int]
,实际上不需要在运行时获取内部类型:您知道它专门是int,所以您可以在任何地方硬编码它
您也可以始终执行type(r.x的实例)
。假设您定义了R.\uuuu init\uuuu
,这样您就保证了x
是用正确类型的值实例化的,所以您可以直接查询它
但是,如果您试图处理G[…]
的多个子类,其中每个子类以不同的方式参数化G[…]
,则可以修改G
的定义,以坚持每个子类指定要使用的类型。例如,也许你可以做一些大致如下的事情:
from typing import *
T = TypeVar('T')
class G(Generic[T]):
x_type: ClassVar[Type[T]]
x: T = None
class R(G[int]):
x_type = int
class S(G[str]):
x_type = str
然后,您可以执行instance\u of_g.x\u type
以返回适当的类型
您可以将这两个答案结合起来——例如,可以设置
G
的构造函数,以便它对给定的x
的任何值调用type(…)
。好吧,假设R
专门继承G[int]
,实际上不需要在运行时获取内部类型:您知道它特别是int,所以您可以在任何地方硬编码它
您也可以始终执行type(r.x的实例)
。假设您定义了R.\uuuu init\uuuu
,这样您就保证了x
是用正确类型的值实例化的,所以您可以直接查询它
但是,如果您试图处理G[…]
的多个子类,其中每个子类以不同的方式参数化G[…]
,则可以修改G
的定义,以坚持每个子类指定要使用的类型。例如,也许你可以做一些大致如下的事情:
from typing import *
T = TypeVar('T')
class G(Generic[T]):
x_type: ClassVar[Type[T]]
x: T = None
class R(G[int]):
x_type = int
class S(G[str]):
x_type = str
然后,您可以执行instance\u of_g.x\u type
以返回适当的类型
您可以将这两个答案结合起来——例如,可以设置
G
的构造函数,以便它对给定的x
的任何值调用type(…)
。谢谢,但这不是我想要的。例如,T
可以是可选的[T]
,您不能只键入它来获取它真正声明的类型。另一个解决方案太麻烦了,恐怕我不想使用它。@XUWeijiang——不幸的是,我不确定是否还有其他解决方案可以解决您的问题:类型提示的设计实际上没有考虑运行时检查。(事实上,我认为它们至少在某种程度上是故意设计来让这类事情变得困难的。)我想如果推到了紧要关头,最后的一个策略是将R.\uuuuu orig\u base.\uuuu
的内容转换成字符串,解析它,然后恢复底层类型应该是什么。谢谢,但这不是我想要的。例如,T
可以是可选的[T]
,您不能只键入它来获取它真正声明的类型。另一个解决方案太麻烦了,恐怕我不想使用它。@XUWeijiang——不幸的是,我不确定是否还有其他解决方案可以解决您的问题:类型提示的设计实际上没有考虑运行时检查。(事实上,我认为他们至少在某种程度上是故意让这类事情变得困难的。)我想如果推到了紧要关头,最后的一个策略是将R.\uuuu orig\u base.\uuuu
的内容转换成字符串,解析它,然后自己恢复底层类型。运行时检查键入
模块中的任何内容仍然处于非常糟糕的状态。几乎任何东西都没有文档化的内省API。对键入模块中任何东西的运行时检查仍然处于非常糟糕的状态。几乎任何东西都没有文档化的内省API。