python - 使用 Python 3.6 在运行时获取类的通用类型

标签 python generics

遵循此问题中描述的解决方案:How to access the type arguments of typing.Generic?

我已经在 Python 3.8 中成功解决了运行时的泛型问题。但是,我似乎无法访问 Python 3.6 解决方案中描述的 __args__ 字段。我不确定为什么,这是我的代码:

def get_generic_type_arg(cls):
    if py_version >= (3, 8):
        t = cls.__orig_bases__[0]
        return get_args(t)[0]
    else:
        t = cls.__args__
        return None

class EventContract:
    @classmethod
    def get_version(cls) -> int:
        return int(cls.__name__[1:])


RT = TypeVar('RT', bound=EventContract)


class QueryContract(Generic[RT], EventContract):
    """ Base class for query contracts that are versioned. """

    @classmethod  # Do not override this
    def get_response_class(cls) -> Type[RT]:
        return get_generic_type_arg(cls)

    def build_result(self, *args, **kwargs):
        return self.get_response_class()(**kwargs)


@dataclasses.dataclass
class V1Response(EventContract):
    value: int


@dataclasses.dataclass
class V1(QueryContract[V1Response]):
    id: int
    name: str

当尝试在 cls 上调用 get_generic_type 时,我得到一个 AttributeError。我还尝试使用 t.__bases__[0] 获取它的基类,这给了我没有通用参数的 QueryContract (__args__ 给了我另一个属性错误)。我在 V1 上调用 get_response_class 方法。有什么想法吗?

最佳答案

我已经想好了怎么做。出于某种原因,__orig_bases__ 无法正常工作,但在重建我的 Python 3.6 并使用 VENV 后,它可以正常工作。这是最终的工作方法:

py_version = sys.version_info
if py_version >= (3, 8):
    from typing import get_args


def get_generic_type_arg(cls):
    t = cls.__orig_bases__[0]
    if py_version >= (3, 8):
        return get_args(t)[0]
    else:
        return t.__args__[0]

Python 3.6 还需要安装 dataclasses 作为一个库,尽管它不是这个问题的一部分。另请注意,__args__ 似乎未在 Python 3.6 中记录并从 Python 3.8 中删除。

关于python - 使用 Python 3.6 在运行时获取类的通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70338370/

相关文章:

Python 。独特订购商品列表

python - 格式化大字符串时出错 - 如何检测错误?

typescript - 在 TypeScript 中,如何获取值为给定类型的对象类型的键?

c# - 获取通用服务类型的所有实现 - 包括开放式通用

generics - 如何让CasSTLe Windsor解析带有约束的泛型?

python - Python不应该将包安装在它自己的目录中吗?

c++ - Python 导入和使用单元格(带有 linux .so 文件)

python - 在 scipy.io.savemat 中以不同的数值数据格式保存 mat 文件

java - 泛型类方法返回它自己的类型作为模板参数

generics - 无法为泛型类型的结构实现fmt::Display