Verschachtelte Daten als Text
JSON ist das Alltagsformat für Konfigurationsdateien und für Daten, die zwischen Programmen und Web-APIs ausgetauscht werden. Es besteht aus Objekten {"key": value}, Arrays [1, 2], Strings, Zahlen, true/false und null. Das entspricht direkt Python: Objekte werden zu Dictionaries, Arrays zu Listen, true/false zu True/False und null zu None. Anders als eine CSV-Tabelle kann JSON verschachtelt sein: Eine Order kann eine Liste von Fills enthalten, jeder mit eigenen Feldern.
import json
# Text to Python: loads() ("load string")
text = '{"symbol": "AAPL", "fills": [{"price": 184.25, "qty": 100}], "open": true, "note": null}'
order = json.loads(text)
print(order["fills"][0]["price"]) # 184.25
print(order["open"], order["note"]) # True None
# Python to text: dumps() ("dump string")
print(json.dumps({"symbol": "AAPL", "qty": 200})) # {"symbol": "AAPL", "qty": 200}Dateien: load und dump
Die Versionen ohne s arbeiten mit Dateien: json.load(file) liest und parst eine geöffnete Datei, json.dump(data, file) schreibt sie. Mit indent=2 wird die Datei für Menschen lesbar, mit sort_keys=True bleibt die Schlüsselreihenfolge stabil, was Unterschiede in der Versionsverwaltung klein hält. Öffnen Sie immer mit with und encoding="utf-8".
import json
# Save a config, then load it back
config = {"fee": 0.001, "symbols": ["MSFT", "AAPL"], "limits": {"max_qty": 500}}
with open("config.json", "w", encoding="utf-8") as file:
json.dump(config, file, indent=2, sort_keys=True)
with open("config.json", encoding="utf-8") as file:
print(file.read())
# {
# "fee": 0.001,
# "limits": {
# "max_qty": 500
# },
# "symbols": [
# "MSFT",
# "AAPL"
# ]
# }
with open("config.json", encoding="utf-8") as file:
print(json.load(file) == config) # TrueWas die Reise nicht übersteht
JSON kennt nur wenige Typen, daher ändern sich manche Python-Werte unterwegs. Tupel kommen als Listen zurück, Dictionary-Schlüssel kommen immer als Strings zurück ({1: "a"} wird zu {"1": "a"}), und Mengen, Datumswerte und eigene Objekte lassen sich gar nicht serialisieren (TypeError), bis Sie sie umwandeln, etwa ein Datum mit .isoformat() oder eine Menge mit sorted(...). Beachten Sie auch: NaN und Unendlich sind kein gültiges JSON.
import json
from datetime import date
# Tuples become lists, int keys become strings
data = {"pair": (1, 2), 7: "seven"}
print(json.loads(json.dumps(data))) # {'pair': [1, 2], '7': 'seven'}
# A date has to be converted by hand
today = date(2025, 1, 2)
print(json.dumps({"day": today.isoformat()})) # {"day": "2025-01-02"}Fehlerhafte Eingabe
Text, der von außen kommt, etwa eine Nachricht einer Börse, ist vielleicht gar kein gültiges JSON. json.loads löst dann json.JSONDecodeError aus, eine Art ValueError, und gültiges JSON kann trotzdem den gewünschten Schlüssel nicht haben (KeyError) oder eine andere Form (TypeError). Fassen Sie das Parsen in try/except und entscheiden Sie, was eine fehlerhafte Nachricht für Ihr Programm bedeutet. Das nächste Thema behandelt Ausnahmen ausführlich.
import json
# Bad input raises, so catch it where you parse
def get_price(text):
try:
return json.loads(text)["price"]
except (ValueError, KeyError, TypeError):
return None
print(get_price('{"price": 184.25}')) # 184.25
print(get_price("not json")) # None
print(get_price('{"symbol": "AAPL"}')) # Nonejson.dumps oder json.dump den Text erzeugen und json.loads oder json.load ihn lesen. Dasselbe gilt beim Zusammenführen von Einstellungen: Kopieren Sie vor dem Ändern, damit eine Konfiguration nicht in eine andere durchsickert.json.loads(text)/json.dumps(data)arbeiten mit Strings;json.load(file)/json.dump(data, file)mit Dateien.indent=2undsort_keys=Truemachen Dateien lesbar und stabil.- Fehlerhafte Eingaben lösen
ValueError,KeyErroroderTypeErroraus: Fangen Sie ab, was Sie erwarten.
Als Nächstes: Ausnahmen und Fehlerbehandlung, damit Ihre Programme deutlich scheitern und sich erholen, wenn sie es sollen.
Lab: Was bewertet wird
- Mit
order_totaldie Orders einer JSON-Datei summieren25 Pkt. - Mit
save_configEinstellungen als lesbares JSON speichern25 Pkt. - Mit
parse_quoteeine Kursnachricht sicher lesen25 Pkt. - Mit
merge_configsEinstellungen über Standardwerte legen25 Pkt.