Python3.7+支持List注解的嵌套dataclass无样板代码实现咨询
嵌套dataclass装饰器支持列表类型方案
核心问题
原装饰器存在两处缺陷:
__init__方法中原始初始化函数o_init的调用缩进错误,放在遍历kwargs的循环内会重复执行初始化,引发异常- 仅支持直接的dataclass类型注解,未处理
List[SomeDataclass]这类泛型容器的注解场景
修改后的装饰器实现
Python3.8+可以直接从typing模块导入get_origin、get_args,Python3.7版本需要先执行pip install typing-extensions,从typing_extensions导入这两个工具函数。
from dataclasses import dataclass, is_dataclass from typing import List, get_origin, get_args from copy import deepcopy def nested_deco(*args, **kwargs): def wrapper(check_class): check_class = dataclass(check_class, **kwargs) o_init = check_class.__init__ def __init__(self, *args, **kwargs): for name, value in kwargs.items(): ft = check_class.__annotations__.get(name, None) if not ft: continue # 处理List[Dataclass]场景 origin_type = get_origin(ft) if origin_type is list and isinstance(value, list): element_type = get_args(ft)[0] if is_dataclass(element_type): kwargs[name] = [element_type(**item) if isinstance(item, dict) else item for item in value] # 处理直接嵌套Dataclass场景 elif is_dataclass(ft) and isinstance(value, dict): kwargs[name] = ft(**value) # 原始初始化移到循环外,仅调用一次 o_init(self, *args, **kwargs) check_class.__init__ = __init__ return check_class return wrapper(args[0]) if args else wrapper
适配说明
你提供的示例中存在类注解和传入数据结构不匹配的问题:你定义的Result类的iteration_results字段注解为IterationResults类型,但测试数据里result下的iteration_results直接是列表,两者不匹配。如果要保留现有类结构,测试数据对应部分需要调整为如下格式,即可正常解析:
"result": { "status": "complete", "iteration_results": { "iterations": [ { "name": "first", "data": { "question1": "yes", "question2": "no" } } ] } }
调整后嵌套结构会全部自动解析为对应dataclass实例,且所有字段类型注解完全保留。
内容的提问来源于stack exchange,提问作者M.wol
相关产品推荐
相关产品推荐

