Python en JSON zijn een natuurlijk duo.
Of je nu een REST API bouwt met FastAPI
of Django,
datapipelines verwerkt of simpelweg een configuratiebestand leest — je werkt voortdurend met JSON.
Het goede nieuws: de standaardbibliotheek van Python heeft alles wat je nodig hebt in de
json-module.
Geen pip install nodig.
De Vier Functies die Je Echt Gebruikt
De json-module geeft je vier functies voor dagelijks gebruik:
json.loads(str)— parseer een JSON-string naar een Python-objectjson.dumps(obj)— converteer een Python-object naar een JSON-stringjson.load(file)— parseer JSON rechtstreeks vanuit een bestandsobjectjson.dump(obj, file)— schrijf een Python-object als JSON naar een bestand
De s in loads / dumps staat voor string.
De varianten zonder s werken met bestandsobjecten. Makkelijk te onthouden als je de regel eenmaal kent.
json.loads() — Een JSON-string Parsen
import json
json_string = '{"name": "Alice", "age": 30, "active": true, "score": 98.5}'
user = json.loads(json_string)
print(user["name"]) # Alice
print(user["age"]) # 30
print(user["active"]) # True
print(type(user)) # <class 'dict'>Let op de type-mapping: JSON true wordt Python True,
JSON false wordt Python False, JSON null wordt Python None.
JSON-objecten worden Python dict, JSON-arrays worden Python list.
json.dumps() — Serialiseren naar een JSON-string
import json
user = {
"name": "Bob",
"age": 25,
"roles": ["admin", "editor"],
"active": True,
"extra": None
}
# Compact (handig voor netwerktransmissie)
compact = json.dumps(user)
print(compact)
# {"name": "Bob", "age": 25, "roles": ["admin", "editor"], "active": true, "extra": null}
# Opgemaakte uitvoer (handig voor logs en menselijke inspectie)
pretty = json.dumps(user, indent=2)
print(pretty)
# {
# "name": "Bob",
# "age": 25,
# "roles": [
# "admin",
# "editor"
# ],
# "active": true,
# "extra": null
# }Let op de omgekeerde type-mapping: Python True → JSON true,
Python None → JSON null. Python regelt dit automatisch.
JSON Lezen uit een Bestand
Dit is waarschijnlijk het meest voorkomende gebruik — een configuratie- of databestand inlezen bij het opstarten:
import json
# Lees en parseer in één stap
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
print(config["database"]["host"]) # localhost
print(config["database"]["port"]) # 5432Geef altijd encoding="utf-8" op bij het openen van JSON-bestanden. JSON is gespecificeerd als UTF-8
door RFC 8259,
en het weglaten hiervan kan problemen veroorzaken op Windows waar de standaardcodering soms cp1252 is.
JSON Schrijven naar een Bestand
import json
results = {
"timestamp": "2024-01-15T09:30:00Z",
"total": 1523,
"processed": 1521,
"failed": 2,
"errors": [
{"id": 42, "reason": "missing field"},
{"id": 99, "reason": "invalid format"}
]
}
with open("results.json", "w", encoding="utf-8") as f:
json.dump(results, f, indent=2)
print("Results saved to results.json")Fouten Correct Afhandelen
json.loads() gooit een
json.JSONDecodeError
(een subklasse van ValueError) wanneer de invoer geen geldige JSON is. Vang dit altijd op wanneer je
data parseert die je niet beheert:
import json
def safe_parse(json_str):
try:
return json.loads(json_str)
except json.JSONDecodeError as e:
print(f"Invalid JSON at line {e.lineno}, column {e.colno}: {e.msg}")
return None
data = safe_parse('{"name": "Alice"}') # works fine
bad = safe_parse('not json at all') # prints error, returns None
also_bad = safe_parse('{"key": }') # prints error with position infoJSONDecodeError geeft je de exacte regel en kolom waar het parsen mislukte,
wat handig is bij het debuggen van grote JSON-bestanden.
Handige dumps()-opties
import json
data = {
"z_key": 1,
"a_key": 2,
"price": 9.999999999
}
# Sorteer sleutels alfabetisch (handig voor reproduceerbare uitvoer / diffs)
print(json.dumps(data, sort_keys=True, indent=2))
# {
# "a_key": 2,
# "price": 9.999999999,
# "z_key": 1
# }
# Zorg dat niet-ASCII-tekens bewaard blijven (standaard: escaped naar \uXXXX)
data2 = {"city": "Münich", "greeting": "こんにちは"}
print(json.dumps(data2, ensure_ascii=False))
# {"city": "Münich", "greeting": "こんにちは"}
# Met ensure_ascii=True (standaard):
print(json.dumps(data2))
# {"city": "M\u00fcnich", "greeting": "\u3053\u3093\u306b\u3061\u306f"}ensure_ascii=False voeg ik altijd toe wanneer ik JSON-bestanden schrijf die
niet-ASCII-tekst bevatten. De escaped versie is technisch geldige JSON maar veel moeilijker te lezen in een teksteditor.
Aangepaste Objecten Serialiseren
Standaard kan json.dumps() geen instanties van aangepaste klassen of
datetime-objecten
serialiseren. Je hebt twee opties: subklasse
json.JSONEncoder,
of converteer eerst naar een dict:
import json
from datetime import datetime, date
# Optie 1: aangepaste encoder-klasse
class AppEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime, date)):
return obj.isoformat()
return super().default(obj)
data = {"name": "Alice", "created_at": datetime(2024, 1, 15, 9, 30)}
print(json.dumps(data, cls=AppEncoder, indent=2))
# {
# "name": "Alice",
# "created_at": "2024-01-15T09:30:00"
# }
# Optie 2: default=-parameter (eenvoudiger voor eenmalige conversies)
print(json.dumps(data, default=str, indent=2)) # converteert alles onbekends naar strEen Praktisch Patroon: Configuratiebestand Laden
Hier is een praktijkpatroon dat ik in bijna elk Python-project gebruik — een configuratielader die een JSON-configuratiebestand leest met verstandige standaardwaarden:
import json
import os
from pathlib import Path
DEFAULTS = {
"database": {"host": "localhost", "port": 5432},
"debug": False,
"log_level": "INFO"
}
def load_config(path="config.json"):
config = DEFAULTS.copy()
config_path = Path(path)
if config_path.exists():
with open(config_path, "r", encoding="utf-8") as f:
try:
user_config = json.load(f)
# Diepe merge: gebruikersinstellingen overschrijven standaardwaarden
for key, value in user_config.items():
if isinstance(value, dict) and key in config:
config[key].update(value)
else:
config[key] = value
except json.JSONDecodeError as e:
print(f"Warning: config.json is invalid ({e.msg}), using defaults")
return config
config = load_config()
print(config["database"]["host"]) # localhost (or overridden value)Samenvatting
De json-module van Python dekt alles wat je nodig hebt zonder externe afhankelijkheden.
De kernregels: gebruik loads()/dumps() voor strings, load()/dump()
voor bestanden, handel altijd JSONDecodeError af bij het parsen van externe data, en voeg
ensure_ascii=False toe wanneer je data niet-Latijnse tekens bevat.
Voor het debuggen van JSON-data kunnen de JSON Formatter en
JSON Validator je veel tijd besparen.