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

如何从Python泛型类型提取类型及参数?兼容3.8+版本的实现方法

兼容Python 3.8+的泛型别名自省方案

针对dataclass自省场景,我们可以通过以下代码实现泛型别名的检查、原始类型(t_orig)和类型参数(t_args)的提取,同时兼容Python 3.8及以上版本,支持3.8的typing.List[int]和3.9+的typing.List[int]、list[int]语法:

import sys
import types
from typing import _GenericAlias

def is_generic_alias(cls) -> bool:
    """判断给定类型是否为泛型别名"""
    # Python 3.9+ 同时支持内置类型泛型别名(types.GenericAlias)和 typing 模块的泛型别名
    if sys.version_info >= (3, 9):
        return isinstance(cls, (types.GenericAlias, _GenericAlias))
    # Python 3.8 仅支持 typing 模块的泛型别名(_GenericAlias)
    else:
        return isinstance(cls, _GenericAlias)

def get_generic_origin(cls):
    """获取泛型别名的原始类型(对应t_orig)"""
    if not is_generic_alias(cls):
        return None
    return getattr(cls, '__origin__', None)

def get_generic_args(cls) -> tuple:
    """获取泛型别名的类型参数(对应t_args)"""
    if not is_generic_alias(cls):
        return ()
    return getattr(cls, '__args__', ())

代码说明

  • is_generic_alias:根据Python版本适配判断逻辑。3.9+新增了内置类型直接泛化的语法(如list[int]),这类实例属于types.GenericAlias;而typing.List[int]在3.9+中与list[int]等价,同时保留对旧版_GenericAlias类型的兼容。
  • get_generic_origin:提取泛型别名对应的原始容器类型,比如List[int]或list[int]的原始类型都是list。
  • get_generic_args:提取泛型别名的类型参数元组,比如Dict[str, int]的参数为(str, int)。

测试示例

Python 3.8环境

from typing import List, Dict

# 检查typing.List[int]
print(is_generic_alias(List[int]))          # 输出: True
print(get_generic_origin(List[int]))        # 输出: <class 'list'>
print(get_generic_args(List[int]))          # 输出: (int,)

# 检查typing.Dict[str, int]
print(is_generic_alias(Dict[str, int]))     # 输出: True
print(get_generic_origin(Dict[str, int]))   # 输出: <class 'dict'>
print(get_generic_args(Dict[str, int]))     # 输出: (str, int)

# 非泛型类型测试
print(is_generic_alias(list))               # 输出: False
print(get_generic_origin(int))              # 输出: None

Python 3.9+环境

from typing import List, Dict

# 兼容旧版typing模块泛型
print(is_generic_alias(List[int]))          # 输出: True
print(get_generic_origin(List[int]))        # 输出: <class 'list'>
print(get_generic_args(List[int]))          # 输出: (int,)

# 支持内置类型直接泛型
print(is_generic_alias(list[int]))          # 输出: True
print(get_generic_origin(list[int]))        # 输出: <class 'list'>
print(get_generic_args(list[int]))          # 输出: (int,)

# 字典类型测试
print(is_generic_alias(dict[str, int]))     # 输出: True
print(get_generic_origin(dict[str, int]))   # 输出: <class 'dict'>
print(get_generic_args(dict[str, int]))     # 输出: (str, int)

内容的提问来源于stack exchange,提问作者hl037_

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 16:45:09