json & Serialization
The json module encodes Python objects to JSON text and parses JSON into dict/list scalars. Customize with default encoders and object_hook for round-trips - for APIs prefer Pydantic 2 at boundaries.
Search across all documentation pages
The json module encodes Python objects to JSON text and parses JSON into dict/list scalars. Customize with default encoders and object_hook for round-trips - for APIs prefer Pydantic 2 at boundaries.
import json
from datetime import datetime, timezone
def default(obj):
if isinstance(obj, datetime):
return obj.astimezone(timezone.utc).isoformat()
raise TypeError(type(obj))
payload = json.dumps({"at": datetime.now(timezone.utc)}, default=default)When to reach for this:
json.loads on trusted small payloadsimport json
from dataclasses import asdict, dataclass
from datetime import datetime, timezone
from pathlib import Path
@dataclass
class Event:
name: str
at: datetime
def encode_event(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(type(obj))
def save_events(path: Path, events: list[Event]) -> None:
raw = [asdict(e) for e in events]
path.write_text(json.dumps(raw, default=encode_event, indent=2), encoding="utf-8")
def load_events(path: Path) -> list[dict]:
return json.loads(path.read_text(encoding="utf-8"))
events = [Event("login", datetime.now(timezone.utc))]
out = Path("events.json")
save_events(out, events)
print(load_events(out))
out.unlink(missing_ok=True)What this demonstrates:
default for non-JSON-native types| Python | JSON |
|---|---|
| dict | object |
| list | array |
| str, int, float, bool, None | scalar |
orjson PyPI faster for hot pathsjson.dumps fine for CLI and configijson streaming or line-delimited.| Alternative | Use When | Don't Use When |
|---|---|---|
| Pydantic | API models validation | Tiny internal dump |
| msgpack | Binary compact IPC | Human-readable need |
| yaml | Human config | Strict JSON API |
loads string; load file object - prefer Path read_text + loads for clarity.
Stable diffs for config - costs sort overhead.
Emit UTF-8 characters in JSON strings - usually desired in 3.x.
Convert to str in default - never float for money.
str(uuid) in default encoder.
Framework jsonable_encoder - pydantic models preferred.
One json.dumps per line written to file or stdout.
jsonschema PyPI or Pydantic after loads.
Never pickle untrusted network data; json for interchange.
No - pretty print for humans only; compact in APIs.
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 19, 2026