Python und JSON sind ein natürliches Paar.
Ob Sie eine REST-API mit FastAPI
oder Django entwickeln,
Datenpipelines verarbeiten oder einfach eine Konfigurationsdatei lesen — Sie arbeiten ständig mit JSON.
Die gute Nachricht: Die Standardbibliothek von Python hat alles, was Sie brauchen, im
json-Modul.
Kein pip install erforderlich.
Die vier Funktionen, die Sie wirklich verwenden
Das json-Modul bietet vier Funktionen für die tägliche Arbeit:
json.loads(str)— parst einen JSON-String in ein Python-Objektjson.dumps(obj)— konvertiert ein Python-Objekt in einen JSON-Stringjson.load(file)— parst JSON direkt aus einem Datei-Objektjson.dump(obj, file)— schreibt ein Python-Objekt als JSON in eine Datei
Das s in loads / dumps steht für String.
Die Funktionen ohne das s arbeiten mit Dateiobjekten. Leicht zu merken, wenn man die Regel kennt.
json.loads() — Einen 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'>Beachten Sie das Typ-Mapping: JSON true wird zu Python True,
JSON false wird zu Python False, JSON null wird zu Python None.
JSON-Objekte werden zu Python dict, JSON-Arrays zu Python list.
json.dumps() — In einen JSON-String serialisieren
import json
user = {
"name": "Bob",
"age": 25,
"roles": ["admin", "editor"],
"active": True,
"extra": None
}
# Kompakt (gut für die Netzwerkübertragung)
compact = json.dumps(user)
print(compact)
# {"name": "Bob", "age": 25, "roles": ["admin", "editor"], "active": true, "extra": null}
# Hübsch formatiert (gut für Logs und menschliche Inspektion)
pretty = json.dumps(user, indent=2)
print(pretty)
# {
# "name": "Bob",
# "age": 25,
# "roles": [
# "admin",
# "editor"
# ],
# "active": true,
# "extra": null
# }Beachten Sie das umgekehrte Typ-Mapping: Python True → JSON true,
Python None → JSON null. Python erledigt das automatisch.
JSON aus einer Datei lesen
Dies ist wahrscheinlich der häufigste Anwendungsfall — das Lesen einer Konfigurations- oder Datendatei beim Start:
import json
# In einem Schritt lesen und parsen
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
print(config["database"]["host"]) # localhost
print(config["database"]["port"]) # 5432Geben Sie beim Öffnen von JSON-Dateien immer encoding="utf-8" an. JSON ist per
RFC 8259
als UTF-8 spezifiziert, und das Weglassen kann unter Windows zu Problemen führen, wo die Standardkodierung manchmal cp1252 ist.
JSON in eine Datei schreiben
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")Fehler richtig behandeln
json.loads() wirft
json.JSONDecodeError
(eine Unterklasse von ValueError), wenn die Eingabe kein gültiges JSON ist. Behandeln Sie dies immer,
wenn Sie Daten parsen, die Sie nicht kontrollieren:
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"}') # funktioniert problemlos
bad = safe_parse('not json at all') # gibt Fehler aus, gibt None zurück
also_bad = safe_parse('{"key": }') # gibt Fehler mit Positionsinfo ausJSONDecodeError gibt die genaue Zeile und Spalte an, wo das Parsen fehlgeschlagen ist,
was beim Debuggen großer JSON-Dateien nützlich ist.
Nützliche dumps()-Optionen
import json
data = {
"z_key": 1,
"a_key": 2,
"price": 9.999999999
}
# Schlüssel alphabetisch sortieren (ideal für reproduzierbare Ausgabe / Diffs)
print(json.dumps(data, sort_keys=True, indent=2))
# {
# "a_key": 2,
# "price": 9.999999999,
# "z_key": 1
# }
# Sicherstellen, dass Nicht-ASCII-Zeichen erhalten bleiben (Standard: als \uXXXX escaped)
data2 = {"city": "Münich", "greeting": "こんにちは"}
print(json.dumps(data2, ensure_ascii=False))
# {"city": "Münich", "greeting": "こんにちは"}
# Mit ensure_ascii=True (Standard):
print(json.dumps(data2))
# {"city": "M\u00fcnich", "greeting": "\u3053\u3093\u306b\u3061\u306f"}ensure_ascii=False füge ich immer hinzu, wenn ich JSON-Dateien mit
Nicht-ASCII-Text schreibe. Die escapte Version ist technisch gültiges JSON, aber in einem Texteditor
viel schwieriger zu lesen.
Benutzerdefinierte Objekte serialisieren
Standardmäßig kann json.dumps() keine Instanzen benutzerdefinierter Klassen oder
datetime-Objekte
serialisieren. Sie haben zwei Möglichkeiten: Erstellen einer Unterklasse von
json.JSONEncoder
oder zuerst in ein dict konvertieren:
import json
from datetime import datetime, date
# Option 1: benutzerdefinierte 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"
# }
# Option 2: default=-Parameter (einfacher für einmalige Konvertierungen)
print(json.dumps(data, default=str, indent=2)) # konvertiert alles Unbekannte zu strEin praktisches Muster: Konfigurationsdatei laden
Hier ist ein Praxismuster, das ich in fast jedem Python-Projekt verwende — ein Konfigurations-Loader, der eine JSON-Konfigurationsdatei mit sinnvollen Standardwerten liest:
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)
# Tiefes Zusammenführen: Benutzereinstellungen überschreiben Standardwerte
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 (oder überschriebener Wert)Fazit
Pythons json-Modul deckt alles ab, was Sie ohne externe Abhängigkeiten benötigen.
Die wichtigsten Regeln: loads()/dumps() für Strings, load()/dump()
für Dateien, immer JSONDecodeError beim Parsen externer Daten behandeln, und
ensure_ascii=False hinzufügen, wenn Ihre Daten Nicht-Latein-Zeichen enthalten.
Beim Debuggen von JSON-Daten können der JSON-Formatierer und der
JSON-Validator viel Zeit sparen.