我需要处理多个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 的 dataclasses 模块与
pydantic
或 dataclasses-json
等库一起使用,自动将 JSON 映射到嵌套的 Python 类。
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 中的约定。
希望这有帮助!