python 41 lines · 6 steps

JSON round-tripping with Python dataclasses

A nested dataclass serializes itself to JSON and rebuilds from it, handling datetimes and nested objects along the way.

Explained by highlit
1import json
2from dataclasses import dataclass, field, asdict
3from datetime import datetime
4from typing import Any
5 
6 
7@dataclass
8class Address:
9 street: str
10 city: str
11 zip_code: str
12 
13 
14@dataclass
15class User:
16 id: int
17 name: str
18 email: str
19 address: Address
20 tags: list[str] = field(default_factory=list)
21 created_at: datetime = field(default_factory=datetime.utcnow)
22 
23 def to_json(self, **kwargs: Any) -> str:
24 def default(obj: Any) -> Any:
25 if isinstance(obj, datetime):
26 return obj.isoformat()
27 raise TypeError(f"Cannot serialize {type(obj).__name__}")
28 
29 return json.dumps(asdict(self), default=default, **kwargs)
30 
31 @classmethod
32 def from_json(cls, raw: str) -> "User":
33 data = json.loads(raw)
34 return cls(
35 id=data["id"],
36 name=data["name"],
37 email=data["email"],
38 address=Address(**data["address"]),
39 tags=data.get("tags", []),
40 created_at=datetime.fromisoformat(data["created_at"]),
41 )
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1asdict recursively flattens nested dataclasses into plain dicts ready for json.dumps.
  2. 2json.dumps accepts a default callback to teach it how to serialize types it doesn't natively understand, like datetime.
  3. 3Reconstruction is manual because JSON has no type info, so nested objects and datetimes must be rebuilt field by field.

Related explainers

Share this explainer

Here's the card — post it anywhere.

JSON round-tripping with Python dataclasses — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code