Back to NiceJSON
NiceJSON Blog/ Working with JSON in Python: Read, Write, and Pretty Print

Working with JSON in Python: Read, Write, and Pretty Print

Use Python's built-in json module to load, dump, and format JSON, handle files, custom types like datetime, and common errors.

2 min read
  • json
  • python
  • tutorial

The json module

Python ships with a json module in the standard library, so there is nothing to install.

FunctionPurpose
json.loads(s)Parse a JSON string
json.load(f)Parse JSON from a file object
json.dumps(obj)Convert an object to a JSON string
json.dump(obj, f)Write an object to a file

Type mapping

JSONPython
objectdict
arraylist
stringstr
numberint or float
true / falseTrue / False
nullNone

Parse a string

import json
 
text = '{"name": "Ada", "age": 36, "tags": ["admin", "dev"]}'
data = json.loads(text)
 
print(data["name"])      # Ada
print(data["tags"][0])   # admin

Read a file

import json
 
with open("data.json", encoding="utf-8") as f:
    data = json.load(f)

Write a file

import json
 
data = {"name": "Ada", "age": 36}
 
with open("out.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

ensure_ascii=False keeps non-ASCII characters such as accents readable instead of escaping them as \u00e9.

Pretty print

print(json.dumps(data, indent=2, sort_keys=True))

From the shell:

python3 -m json.tool data.json

Handle errors

import json
 
try:
    data = json.loads(text)
except json.JSONDecodeError as e:
    print(f"Invalid JSON at line {e.lineno}, column {e.colno}: {e.msg}")

JSONDecodeError gives you the exact position, just like an online validator such as NiceJSON.

Serialize custom types

datetime, Decimal, and custom classes are not serializable by default. Provide a default function:

import json
from datetime import datetime
from decimal import Decimal
 
def encode(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    if isinstance(obj, Decimal):
        return str(obj)
    raise TypeError(f"Cannot serialize {type(obj).__name__}")
 
print(json.dumps({"at": datetime.now(), "price": Decimal("9.99")}, default=encode))

Large files

json.load reads the whole document into memory. For multi-gigabyte data, consider JSON Lines (one JSON object per line) and process it line by line, or a streaming parser such as ijson.

Tips

  • Always specify encoding="utf-8" when opening files.
  • Use separators=(",", ":") to produce minified output.
  • Validate external data before trusting its structure.