I am trying to convert the following to json.
@dataclass
class Attribute:
name: str
description: str
class A:
class B:
attr1 = Attribute(name="attr1",description="description")
attr2 = Attribute(name="attr2",description="description")
class C:
attr3 = Attribute(name="attr3",description="description")
attr4 = Attribute(name="attr4",description="description")
The expected output should be
{
A:{
B:{
attr1:{
name: "attr1",
description: "description"
},
attr2:{
name: "attr2",
description: "description"
}
},
C:{
attr3:{
name: "attr3",
description: "description"
},
attr4:{
name: "attr4",
description: "description"
}
}
}
}
What I have tried without success:
In this case, the simplest option I could suggest would be to define a recursive helper function to iterate over the static fields in a class and call dataclasses.asdict()
on each, such as below.
Note: the following should work in Python 3.8+, as it uses the
:=
walrus operator.
# noinspection PyProtectedMember, PyUnresolvedReferences
from dataclasses import asdict, _FIELDS
def to_dict(o, include_name=False):
# check for dataclass instances
if hasattr(o, _FIELDS):
return asdict(o)
# check we have a class
if not isinstance(o, type):
return None
_dict = {k: res for k, v in o.__dict__.items() if (res := to_dict(v))}
return {o.__qualname__: _dict} if include_name else _dict
Usage would then be as so:
import json
from dataclasses import dataclass
@dataclass
class Attribute:
name: str
description: str
class A:
class B:
attr1 = Attribute(name="attr1", description="description")
attr2 = Attribute(name="attr2", description="description")
class C:
attr3 = Attribute(name="attr3", description="description")
attr4 = Attribute(name="attr4", description="description")
print(json.dumps(to_dict(A, include_name=True), indent=2))
Prints:
{
"A": {
"B": {
"attr1": {
"name": "attr1",
"description": "description"
},
"attr2": {
"name": "attr2",
"description": "description"
}
},
"C": {
"attr3": {
"name": "attr3",
"description": "description"
},
"attr4": {
"name": "attr4",
"description": "description"
}
}
}
}