如何跳过JSON层级将嵌套JSON映射为扁平数据类(无需创建中间层级数据类)
如何跳过JSON层级将嵌套JSON映射为扁平数据类(无需创建中间层级数据类)
我懂你这种需求——不想为了提取几个目标字段就写一堆没用的中间数据类,太繁琐了!下面给你几个直接有效的解决方案,不用跟那些冗余层级打交道:
方法一:手动提取字段(适合结构固定的简单场景)
如果你的JSON结构不会经常变,直接写个小函数把需要的字段从嵌套里挖出来就行,简单直接,不用依赖额外库:
from typing import List from dataclasses import dataclass @dataclass class MyDataClass: key_0: str key_2: str key_3: str key_4_1: str key_5: str @dataclass class MyDataClassList: classes: List[MyDataClass] data = [ { "key_0": "val_0", "key_1_to_skip": { "level_to_skip_1": [ { "level_to_skip_1_1": { "level_to_skip_1_1_1": { "key_2": "value_2", "key_3": "value_3", "key_4": { "key_4_1": "value_4_1", "key_to_ignore_4_2": "value_4_2" } }, }, "key_5": "value_5" } ] }, } ] def flatten_json_to_dataclass(json_item): # 一步步挖取需要的字段 nested_part = json_item["key_1_to_skip"]["level_to_skip_1"][0] return MyDataClass( key_0=json_item["key_0"], key_2=nested_part["level_to_skip_1_1"]["level_to_skip_1_1_1"]["key_2"], key_3=nested_part["level_to_skip_1_1"]["level_to_skip_1_1_1"]["key_3"], key_4_1=nested_part["level_to_skip_1_1"]["level_to_skip_1_1_1"]["key_4"]["key_4_1"], key_5=nested_part["key_5"] ) # 生成实例 flat_classes = [flatten_json_to_dataclass(item) for item in data] result = MyDataClassList(classes=flat_classes) print(result)
运行后就能得到你想要的扁平数据类实例啦,这种方式最直观,适合小范围的固定结构。
方法二:用dataclass-wizard库(推荐,支持字段路径映射)
如果JSON结构复杂或者需要更灵活的映射,dataclass-wizard这个库专门解决dataclass和JSON的转换问题,支持用路径表达式直接绑定嵌套字段,不用写中间类:
首先先安装库:
pip install dataclass-wizard
然后修改你的dataclass,用@json_field装饰器指定每个字段对应的JSON路径:
from typing import List from dataclasses import dataclass from dataclass_wizard import JSONWizard, json_field @dataclass class MyDataClass(JSONWizard): key_0: str # 用路径指定嵌套字段的位置 key_2: str = json_field('key_1_to_skip.level_to_skip_1[0].level_to_skip_1_1.level_to_skip_1_1_1.key_2') key_3: str = json_field('key_1_to_skip.level_to_skip_1[0].level_to_skip_1_1.level_to_skip_1_1_1.key_3') key_4_1: str = json_field('key_1_to_skip.level_to_skip_1[0].level_to_skip_1_1.level_to_skip_1_1_1.key_4.key_4_1') key_5: str = json_field('key_1_to_skip.level_to_skip_1[0].key_5') @dataclass class MyDataClassList: classes: List[MyDataClass] data = [ # 你的原始JSON数据 { "key_0": "val_0", "key_1_to_skip": { "level_to_skip_1": [ { "level_to_skip_1_1": { "level_to_skip_1_1_1": { "key_2": "value_2", "key_3": "value_3", "key_4": { "key_4_1": "value_4_1", "key_to_ignore_4_2": "value_4_2" } }, }, "key_5": "value_5" } ] }, } ] # 直接转换整个列表 flat_classes = [MyDataClass.from_dict(item) for item in data] result = MyDataClassList(classes=flat_classes) print(result)
这个库还支持自动类型转换,比手动提取更省心,适合复杂或者经常变动的JSON结构。
方法三:用pydantic的验证器(适合已有pydantic生态的项目)
如果你已经在使用pydantic,它的dataclass可以通过model_validator手动提取嵌套字段,能和现有的验证逻辑无缝结合:
安装pydantic:
pip install pydantic
示例代码:
from typing import List from pydantic.dataclasses import dataclass from pydantic import model_validator @dataclass class MyDataClass: key_0: str key_2: str key_3: str key_4_1: str key_5: str # 用验证器提前提取嵌套字段 @model_validator(mode='before') def extract_nested_fields(cls, values): nested_part = values["key_1_to_skip"]["level_to_skip_1"][0] return { "key_0": values["key_0"], "key_2": nested_part["level_to_skip_1_1"]["level_to_skip_1_1_1"]["key_2"], "key_3": nested_part["level_to_skip_1_1"]["level_to_skip_1_1_1"]["key_3"], "key_4_1": nested_part["level_to_skip_1_1"]["level_to_skip_1_1_1"]["key_4"]["key_4_1"], "key_5": nested_part["key_5"] } @dataclass class MyDataClassList: classes: List[MyDataClass] data = [ # 原始JSON数据 { "key_0": "val_0", "key_1_to_skip": { "level_to_skip_1": [ { "level_to_skip_1_1": { "level_to_skip_1_1_1": { "key_2": "value_2", "key_3": "value_3", "key_4": { "key_4_1": "value_4_1", "key_to_ignore_4_2": "value_4_2" } }, }, "key_5": "value_5" } ] }, } ] flat_classes = [MyDataClass(**item) for item in data] result = MyDataClassList(classes=flat_classes) print(result)
备注:内容来源于stack exchange,提问作者Zin Yosrim
相关产品推荐
相关产品推荐

