JSON Formatter Python — json.dumps() Guide
Nutze das kostenlose JSON Formatter & Beautifier direkt im Browser – keine Installation erforderlich.
JSON Formatter & Beautifier online testen →Wenn ich einen Python-API-Client debugge, greife ich als erstes zu python json pretty print — ein einziger Aufruf von json.dumps(data, indent=4) und ein unlesbarer einzeiliger Blob wird sofort navigierbar. Pythons eingebautes json-Modul erledigt das vollständig in der Standardbibliothek — kein Drittanbieter-Install erforderlich. Für ein schnelles Einmalergebnis ohne Code ist der JSON Formatter von ToolDeck der direktere Weg. Dieser Leitfaden deckt jede praktische Methode ab: json.dumps() mit allen Parametern, pprint, orjson für hochperformante Formatierung, das json.tool-CLI, und reale Szenarien wie das Formatieren von API-Antworten und Lesen von der Festplatte — alles mit Python-3.8+-kompatiblem Code. Außerdem wird die Serialisierung benutzerdefinierter Typen wie datetime und UUID, das Streaming von Gigabyte-großen Dateien mit ijson, und Terminal-Syntaxhervorhebung mit rich behandelt.
- →
json.dumps(data, indent=4)ist seit Python 2.6 in der Stdlib eingebaut — kein Install nötig. - →Übergib
ensure_ascii=False, wenn deine Daten Umlaute, CJK-Zeichen oder Emoji enthalten. - →Für
datetime,UUIDoder benutzerdefinierte Klassen verwende dendefault=-Parameter oder erstelle eine Unterklasse vonjson.JSONEncoder. - →
separators=(',', ':')entfernt alle Leerzeichen — für Netzwerkübertragung oder URL-Einbettung verwenden. - →
orjsonist 5–10× schneller als die Stdlib und verarbeitetdatetimeunduuid.UUIDnativ. - →
pprint.pprint()gibt Python-Syntax aus (True/None), kein gültiges JSON — niemals für Dateien oder API-Antworten verwenden. - →Bei JSON-Dateien größer als 50 MB mit
ijsonstreamen stattjson.load(), umMemoryErrorzu vermeiden.
Was ist JSON Pretty Printing?
Pretty Printing verwandelt einen dichten, minimierten JSON-String in ein menschenlesbares Format mit konsistenter Einrückung und Zeilenumbrüchen. Die Transformation ist rein kosmetischer Natur: Die Daten sind identisch, nur die Darstellung ändert sich. Pythons json-Modul erledigt dies vollständig in der Standardbibliothek — nichts zu installieren.
{"id":"usr_9f3a2b","name":"Klaus Müller","roles":["admin","editor"],"prefs":{"theme":"dark","lang":"de"}}{
"id": "usr_9f3a2b",
"name": "Klaus Müller",
"roles": [
"admin",
"editor"
],
"prefs": {
"theme": "dark",
"lang": "de"
}
}json.dumps() — Die Standardmethode zur JSON-Formatierung
json.dumps() ist seit Python 2.6 Teil der Standardbibliothek — einfach import json, kein Install nötig. Es serialisiert jedes JSON-kompatible Python-Objekt in einen formatierten String. Der entscheidende Parameter ist indent: auf 4 (oder 2) setzen für lesbare Ausgabe.
import json
benutzer = {
"id": "usr_9f3a2b",
"name": "Klaus Müller",
"roles": ["admin", "editor"],
"prefs": {"theme": "dark", "lang": "de"}
}
print(json.dumps(benutzer, indent=4, ensure_ascii=False))
# Ausgabe:
# {
# "id": "usr_9f3a2b",
# "name": "Klaus Müller",
# "roles": [
# "admin",
# "editor"
# ],
# "prefs": {
# "theme": "dark",
# "lang": "de"
# }
# }Für den Produktionseinsatz möchte man oft sort_keys=True (konsistente Ausgabe über mehrere Läufe) und ensure_ascii=False (Nicht-ASCII-Zeichen lesbar halten):
import json
api_antwort = {
"timestamp": "2024-05-01T10:30:00Z",
"status": "success",
"data": {
"user_id": "usr_9f3a2b",
"display_name": "Anna Schmidt",
"city": "München",
"score": 4892.5,
"tags": ["python", "backend", "api"]
}
}
print(json.dumps(api_antwort, indent=4, sort_keys=True, ensure_ascii=False))
# Ausgabe (Schlüssel sortiert, Umlaute erhalten):
# {
# "data": {
# "city": "München",
# "display_name": "Anna Schmidt",
# "score": 4892.5,
# "tags": ["api", "backend", "python"],
# "user_id": "usr_9f3a2b"
# },
# "status": "success",
# "timestamp": "2024-05-01T10:30:00Z"
# }json.dumps() gibt einen String zurück. Um formatiertes JSON direkt in eine Datei zu schreiben, verwende json.dump(data, f, indent=4) (ohne das s) — es schreibt in ein Datei-Objekt und vermeidet die Erstellung eines Zwischen-Strings im Speicher.json.dumps() Parameter-Referenz
Alle Parameter sind optional außer dem Objekt selbst. Die Standardwerte erzeugen kompaktes, ASCII-sicheres JSON — Parameter explizit übergeben für menschenlesbare Ausgabe.
Kompakte JSON-Ausgabe mit dem separators-Parameter
Standardmäßig trennt json.dumps() Elemente mit ", " und Schlüssel von Werten mit ": ". Der separators-Parameter überschreibt beide. Das Übergeben von (',', ':') entfernt alle Leerzeichen und erzeugt das kompakteste gültige JSON — nützlich für Netzwerkübertragung, URL-Einbettung oder das Speichern von JSON in einer Datenbankspalte, wo jedes Byte zählt.
import json
payload = {
"endpoint": "/api/v2/events",
"filters": {"status": "active", "limit": 100},
"sort": "desc"
}
# Standard — Leerzeichen nach Trennzeichen (lesbar)
standard_ausgabe = json.dumps(payload)
# {"endpoint": "/api/v2/events", "filters": {"status": "active", "limit": 100}, "sort": "desc"}
# len = 88
# Kompakt — keine Leerzeichen
kompakt_ausgabe = json.dumps(payload, separators=(',', ':'))
# {"endpoint":"/api/v2/events","filters":{"status":"active","limit":100},"sort":"desc"}
# len = 80 (9% kleiner; Ersparnis wächst bei größeren, tief verschachtelten Payloads)
# Kompakt + sortierte Schlüssel für reproduzierbare Cache-Schlüssel oder Content-Hashes
kanonisch = json.dumps(payload, separators=(',', ':'), sort_keys=True)
print(kanonisch)
# {"endpoint":"/api/v2/events","filters":{"limit":100,"status":"active"},"sort":"desc"}indent= zusammen mit separators= übergeben wird, steuert das separators-Argument nur die inline-Trennzeichen — Zeilenumbrüche und Einrückung von indent bleiben erhalten. Für kompakte einzeilige Ausgabe indent weglassen (oder None übergeben) und separators=(',', ':') setzen.Benutzerdefinierte Python-Objekte mit dem default-Parameter serialisieren
Das Standard-json-Modul serialisiert Dicts, Listen, Strings, Zahlen, Booleans und None — wirft aber einen TypeError für jeden anderen Typ. Die zwei häufigsten Problemfälle im Produktionscode sind datetime-Objekte und UUIDs.
import json
from datetime import datetime, timezone
import uuid
bestellung = {
"order_id": uuid.uuid4(), # ❌ TypeError: UUID is not JSON serializable
"placed_at": datetime.now(timezone.utc), # ❌ TypeError: datetime is not JSON serializable
"total_eur": 142.50,
"items": ["pro-subscription", "addon-storage"]
}
json.dumps(bestellung) # wirft TypeErrorAnsatz 1 — der default=-Parameter
Übergib einen Callable an default=. json.dumps() ruft ihn für jedes Objekt auf, das es nicht verarbeiten kann. Gib eine serialisierbare Darstellung zurück, oder wirf TypeError für Typen, die du nicht explizit unterstützt — unbekannte Typen niemals stillschweigend ignorieren.
import json
from datetime import datetime, timezone, date
import uuid
from decimal import Decimal
def json_default(obj):
if isinstance(obj, (datetime, date)):
return obj.isoformat()
if isinstance(obj, uuid.UUID):
return str(obj)
if isinstance(obj, Decimal):
return float(obj)
raise TypeError(f"Type {type(obj).__name__!r} is not JSON serializable")
bestellung = {
"order_id": uuid.uuid4(),
"placed_at": datetime(2024, 5, 1, 10, 30, 0, tzinfo=timezone.utc),
"total_eur": Decimal("142.50"),
"items": ["pro-subscription", "addon-storage"]
}
print(json.dumps(bestellung, indent=4, default=json_default))
# {
# "order_id": "a3f1c2d4-e5b6-7890-abcd-ef1234567890",
# "placed_at": "2024-05-01T10:30:00+00:00",
# "total_eur": 142.5,
# "items": ["pro-subscription", "addon-storage"]
# }Ansatz 2 — Unterklasse von json.JSONEncoder
Für wiederverwendbare Kodierungslogik, die über mehrere Module hinweg geteilt wird, ist das Erstellen einer Unterklasse von json.JSONEncoder sauberer als das Herumreichen einer default-Funktion. Überschreibe die default-Methode und rufe super().default(obj) als letzten Fallback auf — das erhält das korrekte Fehlerverhalten für nicht unterstützte Typen.
import json
from datetime import datetime, timezone
import uuid
from decimal import Decimal
class AppEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, uuid.UUID):
return str(obj)
if isinstance(obj, Decimal):
return float(obj)
return super().default(obj) # wirft TypeError für unbekannte Typen
bestellung = {
"order_id": uuid.uuid4(),
"placed_at": datetime(2024, 5, 1, 10, 30, 0, tzinfo=timezone.utc),
"total_eur": Decimal("142.50"),
}
# Encoder-Klasse via cls= übergeben
print(json.dumps(bestellung, indent=4, cls=AppEncoder))
# Identische Ausgabe wie beim default=-Ansatzsuper().default(obj) aufrufen (oder TypeError explizit werfen) für nicht erkannte Typen. Stillschweigend str(obj) für alles zurückzugeben, wird Objekte korrumpieren, die eigentlich einen Fehler hätten auslösen sollen — ein Bug, der in der Produktion schwer zu verfolgen ist.Zurückdecodieren — object_hook
Kodieren ist nur die halbe Wahrheit. Um ein benutzerdefiniertes Python-Objekt aus JSON wiederherzustellen, übergib eine object_hook-Funktion an json.loads() oder json.load(). Der Hook wird für jedes dekodierte JSON-Objekt (Dict) aufgerufen und kann einen beliebigen Python-Wert zurückgeben — so entsteht ein vollständiger Encode ↔ Decode-Roundtrip.
import json
from datetime import datetime
from dataclasses import dataclass
@dataclass
class Event:
name: str
occurred_at: datetime
user_id: str
def encode_event(obj):
if isinstance(obj, Event):
return {
"__type__": "Event",
"name": obj.name,
"occurred_at": obj.occurred_at.isoformat(),
"user_id": obj.user_id,
}
raise TypeError(f"Cannot serialize {type(obj)}")
def decode_event(d):
if d.get("__type__") == "Event":
return Event(
name=d["name"],
occurred_at=datetime.fromisoformat(d["occurred_at"]),
user_id=d["user_id"],
)
return d
# Kodieren
event = Event("login", datetime(2024, 5, 1, 10, 30), "usr_9f3a2b")
json_str = json.dumps(event, default=encode_event, indent=4)
# Zurück in eine Event-Instanz dekodieren
restored = json.loads(json_str, object_hook=decode_event)
print(type(restored)) # <class 'Event'>
print(restored.occurred_at) # 2024-05-01 10:30:00object_hook wird für jedes verschachtelte Dict im Dokument aufgerufen — nicht nur auf oberster Ebene. Ein Diskriminator-Feld einschließen (wie "__type__"), damit der Hook benutzerdefinierte Objekte von einfachen Dicts unterscheiden kann, die unverändert bleiben sollen.pprint — Das alternative Modul (und wann man es nicht verwendet)
Pythons pprint-Modul (Pretty Printer) formatiert Python-Datenstrukturen für die Lesbarkeit im Terminal. Es arbeitet auf geparsten Python-Objekten, nicht auf JSON-Strings — und seine Ausgabe verwendet Python-Syntax, nicht JSON-Syntax.
import json, pprint
raw = '{"sensor_id":"s-441","readings":[23.1,23.4,22.9],"unit":"celsius","active":true}'
data = json.loads(raw)
# pprint — gültiges Python repr, KEIN gültiges JSON
pprint.pprint(data, sort_dicts=False)
# {'sensor_id': 's-441',
# 'readings': [23.1, 23.4, 22.9],
# 'unit': 'celsius',
# 'active': True} ← Python True, nicht JSON true
# json.dumps — gültiges JSON
print(json.dumps(data, indent=4))
# {
# "sensor_id": "s-441",
# "readings": [23.1, 23.4, 22.9],
# "unit": "celsius",
# "active": true ← gültiges JSON
# }pprint-Ausgabe niemals an einen API-Endpunkt senden oder in eine .json-Datei schreiben — sie wird jeden JSON-Parser, der Standardsyntax erwartet, zum Absturz bringen. Verwende json.dumps(indent=4) für alle Ausgaben, die gültiges JSON sein müssen.Wann pprint sinnvoll ist: schnelle Terminal-Inspektion von Python-Objekten im REPL oder Debug-Log, besonders wenn das Objekt nicht JSON-serialisierbare Typen enthält (Sets, benutzerdefinierte Klasseninstanzen, Dataclasses vor der Konvertierung).
Wie man eine JSON-Antwort von Requests formatiert
Das häufigste reale Szenario: Man hat eine JSON-Datei auf der Festplatte oder eine HTTP-Antwort von einer API und möchte sie zum Debuggen oder Loggen formatieren. Beide Fälle verwenden den gleichen Ansatz — als Python-Dict parsen, dann mit json.dumps() formatieren.
Aus einer Datei lesen
import json
try:
with open("config.json", "r", encoding="utf-8") as f:
data = json.load(f)
# In der Konsole ausgeben
print(json.dumps(data, indent=4, ensure_ascii=False))
# Oder die formatierte Version zurück auf die Festplatte schreiben
with open("config.formatiert.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
except json.JSONDecodeError as e:
print(f"Ungültiges JSON: {e}")
except FileNotFoundError:
print(f"Datei nicht gefunden: config.json")Eine API-Antwort formatieren
import json, requests
from requests.exceptions import HTTPError, ConnectionError, Timeout
def api_ausgeben(url: str) -> None:
try:
resp = requests.get(url, timeout=10)
resp.raise_for_status()
print(json.dumps(resp.json(), indent=4, ensure_ascii=False))
except HTTPError as e:
print(f"HTTP {e.response.status_code}: {e}")
except (ConnectionError, Timeout) as e:
print(f"Netzwerkfehler: {e}")
except json.JSONDecodeError:
print(f"Antwort-Body ist kein JSON:\n{resp.text[:500]}")
api_ausgeben("https://api.github.com/repos/python/cpython")response.json() parst den Antwort-Body bereits — kein separates json.loads() nötig. Immer raise_for_status() hinzufügen, bevor auf .json() zugegriffen wird, um 4xx/5xx-Fehler abzufangen, bevor sie einen verwirrenden Parse-Fehler verursachen.Formatierung über die Kommandozeile
Python wird mit json.tool ausgeliefert, einem CLI-Modul zur Formatierung von JSON direkt aus dem Terminal — kein Python-Skript erforderlich. Auf jedem Rechner mit installiertem Python verfügbar.
# Lokale Datei formatieren
python -m json.tool config.json
# API-Antwort durch Formatter leiten
curl -s https://api.github.com/users/gvanrossum | python -m json.tool
# Von stdin formatieren
echo '{"service":"api-gateway","version":"2.1.0","healthy":true}' | python -m json.tool
# Schlüssel alphabetisch sortieren
python -m json.tool --sort-keys data.json
# Benutzerdefinierte Einrückung (Python 3.9+)
python -m json.tool --indent 2 data.json--indent und --no-indent hinzugefügt. Für leistungsfähigeres Terminal-JSON-Filtering empfiehlt sich jq — aber python -m json.tool deckt den Formatierungs-Anwendungsfall ohne zusätzliche Abhängigkeiten ab.Wenn Sie überhaupt kein Terminal haben — etwa beim Einfügen einer Postman-Antwort oder einer Log-Datei — erlaubt der ToolDeck JSON Formatter das Einfügen, Formatieren und Kopieren in einem Schritt mit integrierter Syntaxhervorhebung und Validierung.
Alternative Bibliotheken: orjson und rich
orjson — 5–10× schneller mit nativem Typ-Support
Das Standard- json-Modul ist für die meisten Anwendungsfälle schnell genug, aber wenn man tausende Objekte pro Sekunde serialisiert — Logging-Pipelines, hochdurchsatzige APIs, große Datenexporte — ist orjson 5–10× schneller. Es verarbeitet auch nativ Typen, die die Standardbibliothek ohne eine benutzerdefinierte default-Funktion nicht serialisieren kann: datetime, uuid.UUID, numpy-Arrays und Dataclasses.
pip install orjson
import orjson
from datetime import datetime, timezone
import uuid
event = {
"event_id": uuid.uuid4(), # kein str() nötig — orjson verarbeitet UUID
"timestamp": datetime.now(timezone.utc), # kein isoformat() nötig
"service": "auth-service",
"level": "INFO",
"payload": {
"user_id": "usr_9f3a2b",
"action": "login",
"ip": "192.168.1.42",
"latency_ms": 34
}
}
# orjson.dumps gibt bytes zurück; .decode() konvertiert zu str
print(orjson.dumps(event, option=orjson.OPT_INDENT_2).decode())
# {
# "event_id": "a3f1c2d4-e5b6-7890-abcd-ef1234567890",
# "timestamp": "2024-05-01T10:30:00+00:00",
# "service": "auth-service",
# ...
# }Zwei wichtige Hinweise: orjson.dumps() gibt bytes zurück, keinen String — .decode() aufrufen, wenn ein String benötigt wird. Es unterstützt nur 2-Leerzeichen-Einrückung via OPT_INDENT_2; für 4-Leerzeichen-Ausgabe das Standard-json.dumps(indent=4) verwenden.
rich — Syntaxhervorhebung im Terminal
Wenn man regelmäßig JSON im Terminal oder REPL inspiziert, rendert rich farbcodierte, syntaxhervorgehobene Ausgabe, die tief verschachtelte Strukturen auf einen Blick lesbar macht. Schlüssel, Strings, Zahlen und Booleans erhalten je eine eigene Farbe — viel einfacher zu scannen als eine Wand monochromen Texts. Es ist ein reines Debug-Tool, nicht für die Serialisierung in der Produktion.
pip install rich
from rich import print_json
import json
# print_json() akzeptiert einen JSON-String
raw = '{"event":"login","user_id":"usr_9f3a2b","timestamp":"2024-05-01T10:30:00Z","success":true,"meta":{"ip":"192.168.1.42","attempts":1}}'
print_json(raw)
# Um ein Python-Dict zu formatieren, zuerst in String konvertieren
data = {
"status": "success",
"count": 42,
"tags": ["python", "api", "backend"]
}
print_json(json.dumps(data))rich.print_json() gibt ANSI-Escape-Codes für Terminal-Farbe aus — diese Ausgabe niemals erfassen und in eine .json-Datei schreiben oder als API-Antwort senden. Für maschinenlesbare Ausgabe json.dumps(indent=4) verwenden.simplejson — Drop-in-Kompatibilitätsersatz
simplejson ist die Bibliothek, die Pythons Standard-json-Modul wurde — sie wird weiterhin unabhängig gepflegt und ist der Stdlib bei kleineren Features voraus. Es ist ein echter Drop-in-Ersatz: Den Import austauschen, und der Rest des Codes bleibt unverändert. Nützlich, wenn man Decimal-Support ohne benutzerdefinierten Encoder braucht, oder wenn man ältere Python-Umgebungen unterstützt.
pip install simplejson
import simplejson as json # identische API wie stdlib
from decimal import Decimal
bestellung = {
"item": "API-Abonnement Berlin",
"price": Decimal("49.99"), # stdlib json würde hier TypeError werfen
"quantity": 3,
}
# simplejson serialisiert Decimal nativ — kein default= nötig
print(json.dumps(bestellung, indent=4, use_decimal=True))
# {
# "item": "API-Abonnement Berlin",
# "price": 49.99,
# "quantity": 3
# }orjson die bessere Wahl.simplejson wählen, wenn native Decimal-Serialisierung ohne benutzerdefinierten Encoder benötigt wird, oder wenn eine Codebasis gepflegt wird, die es bereits verwendet.Große JSON-Dateien ohne Speicherprobleme verarbeiten
json.load() liest die gesamte Datei in den Speicher, bevor auf ein einzelnes Feld zugegriffen werden kann. Bei einer Datei mit Millionen von Datensätzen oder einem Payload über einem Gigabyte führt das zu einem MemoryError — oder zwingt den Prozess im besten Fall, auf die Festplatte auszulagern und sehr langsam zu werden.
Streaming mit ijson
ijson ist ein streaming JSON-Parser, der Elemente einzeln aus einem Datei-Objekt generiert. Man iteriert über Array-Elemente, ohne den gesamten Datensatz im Speicher zu halten — der Spitzenspeicherverbrauch bleibt proportional zu einem einzelnen Objekt, nicht zur Dateigröße.
pip install ijson
import ijson
from decimal import Decimal
# events.json Struktur: {"events": [...Millionen von Objekten...]}
gesamtumsatz = Decimal("0")
login_anzahl = 0
with open("events.json", "rb") as f: # ijson erfordert Binärmodus
for event in ijson.items(f, "events.item"):
if event.get("type") == "purchase":
gesamtumsatz += Decimal(str(event["amount_eur"]))
elif event.get("type") == "login":
login_anzahl += 1
print(f"Umsatz: {gesamtumsatz:.2f} EUR | Logins: {login_anzahl}")
# Verarbeitet eine 2-GB-Datei mit ~30 MB Spitzenspeicherverbrauchjson.load() zu ijson wechseln, wenn die Datei ungefähr 50–100 MB überschreitet. Unterhalb dieser Schwelle ist json.load() einfacher und deutlich schneller, da es intern einen C-Extension-Parser verwendet. Über 100 MB überwiegen die Speichereinsparungen durch Streaming den zusätzlichen Overhead.NDJSON — ein JSON-Objekt pro Zeile
NDJSON (Newline Delimited JSON, auch JSON Lines oder .jsonl genannt) speichert ein vollständiges JSON-Objekt pro Zeile. Log-Exporter, Kafka-Consumer und Datenpipelines produzieren dieses Format häufig, weil jede Zeile unabhängig angehängt und gelesen werden kann. Die Standardbibliothek verarbeitet es ohne zusätzliche Abhängigkeiten.
import json
from pathlib import Path
# NDJSON schreiben — ein Event pro Zeile
events = [
{"ts": "2024-05-01T10:00:00Z", "user": "usr_9f3a2b", "action": "login"},
{"ts": "2024-05-01T10:01:03Z", "user": "usr_9f3a2b", "action": "purchase", "sku": "pro-plan"},
{"ts": "2024-05-01T10:15:42Z", "user": "usr_4ab1d9", "action": "login"},
]
with open("events.ndjson", "w", encoding="utf-8") as f:
for event in events:
f.write(json.dumps(event, ensure_ascii=False) + "\n")
# NDJSON lesen — konstanter Speicher, unabhängig von der Dateigröße
kauf_anzahl = 0
with open("events.ndjson", "r", encoding="utf-8") as f:
for zeile in f:
zeile = zeile.strip()
if not zeile: # leere Zeilen überspringen
continue
event = json.loads(zeile)
if event.get("action") == "purchase":
kauf_anzahl += 1
print(f"{event['ts']} — {event['user']} kaufte {event['sku']}")Häufige Fehler
Diese vier Fehler sehe ich in fast jeder Code-Review, die JSON-Serialisierung betrifft — besonders bei Entwicklern, die von JavaScript kommen, wo JSON.stringify die Kodierung automatisch übernimmt.
Problem: print() auf einem Dict verwendet Python repr — die Ausgabe zeigt True/None (Python-Syntax), nicht true/null (JSON-Syntax). Es ist kein gültiges JSON.
Lösung: Immer json.dumps(data, indent=4) für gültige, lesbare JSON-Ausgabe verwenden.
data = {"active": True, "count": None}
print(data)
# {'active': True, 'count': None}print(json.dumps(data, indent=4))
# {
# "active": true,
# "count": null
# }Problem: Sonderzeichen (Umlaute, CJK, Emoji) werden zu \\uXXXX-Sequenzen escaped, was die Ausgabe unlesbar macht.
Lösung: ensure_ascii=False übergeben, um die originalen Unicode-Zeichen zu erhalten.
user = {"name": "Klaus Müller", "city": "München"}
json.dumps(user, indent=2)
# {"name": "Klaus M\u00fcller", "city": "M\u00fcnchen"}json.dumps(user, indent=2, ensure_ascii=False)
# {"name": "Klaus Müller", "city": "München"}Problem: json.dumps() gibt einen String zurück; man braucht dann einen separaten f.write()-Aufruf, was einen unnötigen Zwischen-String erzeugt.
Lösung: json.dump(data, f, indent=4) verwenden — schreibt direkt in das Datei-Objekt.
with open("out.json", "w") as f:
f.write(json.dumps(data, indent=4))with open("out.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)Problem: pprint.pprint() verwendet Python-Syntax (True, None, einfache Anführungszeichen), die JSON-Parser ablehnen.
Lösung: json.dumps(indent=4) für jede Ausgabe verwenden, die als JSON parsebar sein muss.
import pprint
pprint.pprint({"running": True, "last_error": None})
# {'running': True, 'last_error': None}import json
print(json.dumps({"running": True, "last_error": None}, indent=4))
# {"running": true, "last_error": null}Methodenvergleich — json.dumps, orjson, simplejson, rich
json.dumps() für alltägliche Formatierung und Dateischreibvorgänge verwenden — es deckt 95% der Anwendungsfälle ohne Abhängigkeiten ab. Auf orjson zurückgreifen, wenn in einem Hot Path serialisiert wird oder wenn Objekte datetime- und UUID-Felder enthalten.simplejson verwenden, wenn Drop-in-Stdlib-Kompatibilität mit Decimal-Support direkt aus der Box benötigt wird. rich.print_json() und pprint streng für die lokale Terminal-Inspektion reservieren — keines der beiden erzeugt maschinenlesbare Ausgabe.
Häufig gestellte Fragen
Wie formatiere ich JSON in Python lesbar?
Rufe json.dumps(data, indent=4) auf. Der indent-Parameter legt die Anzahl der Leerzeichen pro Verschachtelungsebene fest. Importiere zuerst das json-Modul — es ist in der Standardbibliothek von Python enthalten, kein pip install erforderlich. Übergib ensure_ascii=False, wenn deine Daten Umlaute, CJK-Zeichen oder andere nicht-ASCII-Zeichen enthalten.
import json
benutzer = {"username": "kmueller", "plan": "enterprise", "berechtigungen": ["lesen", "schreiben", "deploy"]}
print(json.dumps(benutzer, indent=4, ensure_ascii=False))Was ist der Unterschied zwischen json.dumps() und json.dump()?
json.dumps() (mit "s") gibt einen formatierten String im Speicher zurück. json.dump() (ohne "s") schreibt direkt in ein dateiähnliches Objekt — übergib das geöffnete Datei-Handle als zweites Argument. Um formatiertes JSON auf die Festplatte zu schreiben, ist json.dump(data, f, indent=4) idiomatisch und vermeidet die Erstellung eines Zwischen-Strings.
# dumps → String im Speicher
formatiert = json.dumps(data, indent=4)
# dump → direkt in Datei schreiben
with open('ausgabe.json', 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4)Warum zeigt json.dumps() \u00fc\u00e4\u00f6 statt der eigentlichen Zeichen?
Standardmäßig escaped ensure_ascii=True jeden nicht-ASCII-Zeichen zu einer \uXXXX-Sequenz. Setze ensure_ascii=False, um die originalen Unicode-Zeichen zu erhalten. Dies ist besonders wichtig für Namen, Adressen und nutzergenerierte Inhalte mit deutschen Umlauten oder anderen nicht-lateinischen Schriften.
data = {"stadt": "München", "gruesse": "Grüß Gott", "land": "Österreich"}
# Standard — escaped
json.dumps(data, indent=4)
# {"stadt": "M\u00fcnchen", "gruesse": "Gr\u00fc\u00df Gott", ...}
# Lesbar
json.dumps(data, indent=4, ensure_ascii=False)
# {"stadt": "München", "gruesse": "Grüß Gott", "land": "Österreich"}Wie formatiere ich einen JSON-String (kein Dict)?
Zuerst den String mit json.loads() parsen, dann mit json.dumps() formatieren. Beide Aufrufe können für eine schnelle Terminal-Inspektion in einer Zeile verkettet werden.
import json
raw = '{"endpoint":"/api/v2/benutzer","timeout":30,"wiederholen":true}'
print(json.dumps(json.loads(raw), indent=4))Kann ich pprint verwenden, um JSON in Python zu formatieren?
pprint.pprint() erzeugt Python-Objekt-Darstellung, kein gültiges JSON. Es verwendet True/False/None (Python-Syntax) statt true/false/null (JSON-Syntax). Übergib die pprint-Ausgabe niemals an eine API oder einen JSON-Parser — verwende json.dumps(indent=4) für alles, das gültiges JSON sein muss.
import pprint, json
data = {"aktiv": True, "punktzahl": None}
pprint.pprint(data) # {'aktiv': True, 'punktzahl': None} ← kein JSON
json.dumps(data, indent=4) # {"aktiv": true, "punktzahl": null} ← gültiges JSONWie sortiere ich JSON-Schlüssel alphabetisch in Python?
Füge sort_keys=True zu json.dumps() hinzu. Für die Kommandozeile verwende python -m json.tool --sort-keys data.json. Sortierte Schlüssel machen JSON-Diffs lesbar und helfen, geänderte Werte auf einen Blick zu erkennen.
import json
server = {"workers": 4, "host": "0.0.0.0", "port": 8080, "debug": False}
print(json.dumps(server, indent=4, sort_keys=True))
# {
# "debug": false,
# "host": "0.0.0.0",
# "port": 8080,
# "workers": 4
# }Python gibt Ihnen volle Kontrolle — eigene Serialisierer, Streaming, Pipeline-Integration. Wenn Sie nur einen formatierten Snippet inspizieren oder teilen möchten, ist der ToolDeck JSON Formatter der schnellere Weg: JSON einfügen und ein eingerücktes, hervorgehobenes Ergebnis ohne Umgebungseinrichtung erhalten.
Verwandte Tools
Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.
Dmitri is a DevOps engineer who relies on Python as his primary scripting and automation language. He builds internal tooling, CI/CD pipelines, and infrastructure automation scripts that run in production across distributed teams. He writes about the Python standard library, subprocess management, file processing, encoding utilities, and the practical shell-adjacent Python that DevOps engineers use every day.