如何判断Python Dataclass中的字段是否为任意类型的Dict?
问题
我想了解判断Python dataclass字段类型的正确方法,尤其是针对在dataclass中指定了键值类型的Dict字段,是否可以忽略键值类型,仅检测字段是否为Dict类型?
以下是带类型提示的简单dataclass示例:
# -*- Python Version: 3.7 -*- from dataclasses import dataclass, field, fields from typing import Dict @dataclass class Example: attr_dict_a: Dict[str, int] = field(default_factory=dict) attr_dict_b: Dict[int, int] = field(default_factory=dict)
我尝试了两种判断方式,但都无法匹配所有Dict类型字段:
x = Example({"1":1}, {1:1}) # 与无类型Dict比较 for field in fields(x): print(field.name, field.type, field.type == Dict) # >>> attr_dict_a typing.Dict[str, int] False # >>> attr_dict_b typing.Dict[int, int] False # 与指定键值类型的Dict比较 for field in fields(x): print(field.name, field.type, field.type == Dict[str, int]) # >>> attr_dict_a typing.Dict[str, int] True # 指定键值类型时生效 # >>> attr_dict_b typing.Dict[int, int] False
如果想对任意类型的Dict(无论键值类型提示如何)执行操作,正确的评估方法是什么?
解决方案
要忽略Dict的泛型参数,仅判断字段是否为Dict类型,可通过以下方法实现:
方法1:Python 3.8+ 推荐使用 get_origin
借助typing模块的get_origin函数提取泛型类型的原始类:
from typing import get_origin x = Example({"1":1}, {1:1}) for field in fields(x): if get_origin(field.type) is Dict: print(f"{field.name} 属于Dict类型") else: print(f"{field.name} 不属于Dict类型")
输出结果:
attr_dict_a 属于Dict类型 attr_dict_b 属于Dict类型
方法2:兼容Python 3.7的方案
Python 3.7中没有get_origin,可直接访问泛型类型的__origin__内部属性:
x = Example({"1":1}, {1:1}) for field in fields(x): field_type = field.type if hasattr(field_type, "__origin__") and field_type.__origin__ is Dict: print(f"{field.name} 属于Dict类型") else: print(f"{field.name} 不属于Dict类型")
补充说明
get_origin不仅适用于Dict,对List、Set等其他泛型类型也有效,能准确返回原始类型。- 如果需要获取Dict的键值类型,可搭配
get_args函数使用,例如get_args(field.type)会返回(str, int)这样的元组。
内容的提问来源于stack exchange,提问作者Ed May
相关产品推荐
相关产品推荐

