将 JSON 转换为一组嵌套的 Python 类

问题描述 投票:0回答:2

我需要处理多个JSON格式的消息。每条消息都有自己的嵌套结构。我想创建一个 Python SDK 来处理这些消息。我的想法是将每个 JSON 结构映射到一组嵌套的 Python 类中。目前,我正在手动执行此操作。但这是一项乏味的任务。

请在下面找到示例 JSON 消息:

{
    "GlobalGnbId": {
        "PlmnIdentity": {
            "Data": [
                 19,
                241,
                132
            ]
        },
        "GnbId": {
            "Value":   1,
            "Length": 22
        }
    },
    "OptionalGnbDuId": 1
}

请在下面找到我自己手工制作的一组 Python 类来处理此 JSON 消息:

class PlmnIdentity(BaseModel):
    """Class for PLMN identity"""
    Data: list[int]

class GnbId(BaseModel):
    """Class for gNodeB ID"""
    Value:  int
    Length: int

class GlobalGnbId(BaseModel):
    """Class for global gNodeB ID"""
    PlmnIdentity:    PlmnIdentity
    GnbId:           GnbId

class NodeId(BaseModel):
    """Class for node ID"""
    GlobalGnbId:     GlobalGnbId
    OptionalGnbDuId: int

最后,请在下面找到一个完整的最小示例:

from pydantic import BaseModel, TypeAdapter

import json

class PlmnIdentity(BaseModel):
    """Class for PLMN identity"""
    Data: list[int]

class GnbId(BaseModel):
    """Class for gNodeB ID"""
    Value:  int
    Length: int

class GlobalGnbId(BaseModel):
    """Class for global gNodeB ID"""
    PlmnIdentity:    PlmnIdentity
    GnbId:           GnbId

class NodeId(BaseModel):
    """Class for node ID"""
    GlobalGnbId:     GlobalGnbId
    OptionalGnbDuId: int

node_id_str = \
"""
{
    "GlobalGnbId": {
        "PlmnIdentity": {
            "Data": [
                 19,
                241,
                132
            ]
        },
        "GnbId": {
            "Value":   1,
            "Length": 22
        }
    },
    "OptionalGnbDuId": 1
}
"""

# NodeId as class
node_id_class = TypeAdapter(NodeId).validate_json(node_id_str)

print(node_id_class)

print(node_id_class.GlobalGnbId)
print(node_id_class.GlobalGnbId.PlmnIdentity)
print(node_id_class.GlobalGnbId.PlmnIdentity.Data)

print(node_id_class.GlobalGnbId.GnbId)
print(node_id_class.GlobalGnbId.GnbId.Value)
print(node_id_class.GlobalGnbId.GnbId.Length)

print(node_id_class.OptionalGnbDuId)

# NodeId as dictionary
node_id_dict = node_id_class.model_dump()

print(node_id_dict)

我的问题是有一种自动或半自动的方法将嵌套的 JSON 消息映射到一组 Python 类吗?

python json dictionary class
2个回答
0
投票

您可以将 Python 的 dataclasses 模块与

pydantic
dataclasses-json
等库一起使用,自动将 JSON 映射到嵌套的 Python 类。


0
投票

我强烈建议探索

dataclass-wizard
!这个快速、强类型的反/序列化库基于
dataclasses
构建,具有最小的依赖性。它经过充分测试并准备好用于生产。

免责声明:我是这个库的作者/维护者。

生成数据类架构

我使用附带的

wiz
CLI 实用程序为您的 JSON 数据生成架构:

echo '{
    "GlobalGnbId": {
        "PlmnIdentity": {
            "Data": [
                 19,
                241,
                132
            ]
        },
        "GnbId": {
            "Value":   1,
            "Length": 22
        }
    },
    "OptionalGnbDuId": 1
}' | wiz gs -x

这给了我可以使用的 Python

dataclass
模式:

from __future__ import annotations

from dataclasses import dataclass

from dataclass_wizard import JSONWizard


@dataclass
class Data(JSONWizard):
    """
    Data dataclass

    """
    global_gnb_id: GlobalGnbId
    optional_gnb_du_id: int


@dataclass
class GlobalGnbId:
    """
    GlobalGnbId dataclass

    """
    plmn_identity: PlmnIdentity
    gnb_id: GnbId


@dataclass
class PlmnIdentity:
    """
    PlmnIdentity dataclass

    """
    data: list[int]


@dataclass
class GnbId:
    """
    GnbId dataclass

    """
    value: int
    length: int

现在我可以继续使用数据类向导库对数据进行反/序列化:

from __future__ import annotations

from dataclasses import dataclass

from dataclass_wizard import JSONWizard


@dataclass
class Data(JSONWizard):
    """
    Data dataclass

    """
    global_gnb_id: GlobalGnbId
    optional_gnb_du_id: int


@dataclass
class GlobalGnbId:
    """
    GlobalGnbId dataclass

    """
    plmn_identity: PlmnIdentity
    gnb_id: GnbId


@dataclass
class PlmnIdentity:
    """
    PlmnIdentity dataclass

    """
    data: list[int]


@dataclass
class GnbId:
    """
    GnbId dataclass

    """
    value: int
    length: int

d = Data.from_json("""
{
    "GlobalGnbId": {
        "PlmnIdentity": {
            "Data": [
                 19,
                241,
                132
            ]
        },
        "GnbId": {
            "Value":   1,
            "Length": 22
        }
    },
    "OptionalGnbDuId": 1
}
""")

print(repr(d))

结果:

Data(global_gnb_id=GlobalGnbId(plmn_identity=PlmnIdentity(data=[19, 241, 132]), gnb_id=GnbId(value=1, length=22)), optional_gnb_du_id=1)

如您所见,主要好处之一是自动字母大小写转换,例如JSON 输入中的

TitleCase
会自动映射到
snake_case
字段名称,这是 Python 中的约定。

希望这有帮助!

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.