I have an array of data classes I need to serialize to JSON. I wrap the list in a class (Persons
)
@attrs.frozen
class Person:
name: str
age: int
grades: Dict[str, int]
@attrs.define
class Persons:
persons: List[Person] = attrs.field(factory=list)
def add(self, person: Person) -> None:
self.persons.append(person)
def run(filename: str) -> None:
college = Persons()
college.add(Person("uzi" , 51, {"math": 100, "cs": 90}))
college.add(Person("dave", 76, {"math": 94, "music": 92}))
college.add(Person("dan", 22, {"bible": 98}))
with open(filename, "w ") as fl:
fl.write(f"{json.dumps(attrs.asdict(college), indent=4)}\n")
Can I somehow get rid of the wrapping class and still serialize a List[Person]
easily?
CodePudding user response:
You can use default
argument of the json.dumps
function and pass the function attrs.asdict
to serialize it.
I have added the "persons" key so it matches the output of your code.
import json
import attrs
@attrs.frozen
class Person:
name: str
age: int
grades: dict[str, int]
def run(filename: str) -> None:
college = []
college.append(Person("uzi", 51, {"math": 100, "cs": 90}))
college.append(Person("dave", 76, {"math": 94, "music": 92}))
college.append(Person("dan", 22, {"bible": 98}))
with open(filename, "w ") as fl:
fl.write(
f"{json.dumps({'persons': college}, default=attrs.asdict, indent=4)}\n"
)
run("my_json.json")
Output
{
"persons": [
{
"name": "uzi",
"age": 51,
"grades": {
"math": 100,
"cs": 90
}
},
{
"name": "dave",
"age": 76,
"grades": {
"math": 94,
"music": 92
}
},
{
"name": "dan",
"age": 22,
"grades": {
"bible": 98
}
}
]
}