Zum Inhalt springen
aviral gupta

// B5.4 · ca. 25 Min. · Einstieg

Strukturierte Daten mit JSON speichern

Nach dieser Lektion speichern Sie Listen und Dictionaries in einer JSON-Datei, laden sie wieder und sagen vorher, was sich unterwegs ändert: Tupel, Zahlenschlüssel und Sets.

Lektion 4 von 5 in B5 Module, Dateien und Fehler

Danach können Sie

  • Python-Daten mit json.dumps und json.loads in JSON-Text und zurück verwandeln, mit indent lesbar eingerückt
  • Daten mit json.dump in einer Datei speichern und mit json.load wieder laden
  • Vorhersagen, was JSON ändert oder ablehnt: Tupel werden Listen, Schlüssel werden Strings, Sets scheitern
  1. Aufwärmen · Aufgabe 1 von 7

    Aufwärmen aus der letzten Lektion: Welche Aussagen über Dateien stimmen? Wählen Sie alle zutreffenden.

    Wählen Sie alle zutreffenden aus.

  2. Vorhersagen · Aufgabe 2 von 7

    Sagen Sie es vorher, bevor Sie weiterlesen: Was gibt das aus?

    import json
    
    print(json.dumps({"name": "Ada", "active": True, "score": None}))
  3. Üben · Aufgabe 3 von 7

    Setzen Sie die Funktion ein, die den JSON-Text in Python-Daten verwandelt.

    import json
    
    text = '{"x": 1, "y": [2, 3]}'
    data = json.____(text)
    print(data["y"][1])
    json.(text)
  4. Üben · Aufgabe 4 von 7

    Ein Dictionary mit Zahlen als Schlüsseln geht nach JSON und zurück. Was gibt das aus?

    import json
    
    print(json.loads(json.dumps({1: "a", 2: "b"})))
  5. Üben · Aufgabe 5 von 7

    Ordnen Sie jedem Python-Wert zu, was json.dumps dafür schreibt.

  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. Ein Tupel geht nach JSON und zurück. Was gibt das aus?

    import json
    
    point = (3, 4)
    back = json.loads(json.dumps(point))
    print(back == point, back)
  7. Anwenden · Aufgabe 7 von 7

    Mini-Aufgabe. Speichern Sie settings = {"theme": "dark", "font_size": 14} mit indent=2 in settings.json. Laden Sie die Datei dann, erhöhen Sie font_size um 2, speichern Sie erneut, und laden und drucken Sie sie noch einmal. Öffnen Sie die Datei im Editor oder geben Sie ihren Text aus, um die Einrückung zu sehen.

    Prüfen Sie Ihr Ergebnis anhand dieser Liste

Selbst programmieren

Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.

Ausgearbeitetes Beispiel

Ein Adressbuch in einer JSON-Datei

Eine Liste von Kontakt-Dictionaries wird mit json.dump und indent=2 gespeichert, die rohe Datei ausgegeben, damit Sie echtes JSON sehen, und mit json.load wieder geladen. Die letzte Zeile nutzt json.dumps, das den Text zurückgibt, statt ihn zu schreiben.

main.py

import json

contacts = [
    {"name": "Ada", "phone": "+49 30 1234", "tags": ["work"]},
    {"name": "Grace", "phone": None, "tags": []},
]

with open("contacts.json", "w", encoding="utf-8") as f:
    json.dump(contacts, f, indent=2)

with open("contacts.json", encoding="utf-8") as f:
    print(f.read())

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

print(loaded == contacts, loaded[1]["phone"])
print(json.dumps({"total": 2, "ok": True}))

Ausführen mit

python main.py

Ausgabe

[
  {
    "name": "Ada",
    "phone": "+49 30 1234",
    "tags": [
      "work"
    ]
  },
  {
    "name": "Grace",
    "phone": null,
    "tags": []
  }
]
True None
{"total": 2, "ok": true}
  • indent=2 setzt jedes Element in eine eigene Zeile, zwei Leerzeichen mehr pro Ebene; eine leere Liste bleibt [].
  • Pythons None wird als null gespeichert und kommt als None zurück.
  • loaded == contacts ist True: Listen, Dictionaries, Strings und None überstehen den Weg unverändert.
  • Ohne indent schreibt dumps alles in eine Zeile.
Ändern und ausführen

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.

Übungen

Übung 1 von 2

Beliebige Daten speichern und laden

Schreiben Sie save_json(path, data), das data als JSON mit 2 Leerzeichen Einrückung in die Datei schreibt und den alten Inhalt ersetzt, und load_json(path), das die Datei liest und die Daten zurückgibt. Nutzen Sie json.dump und json.load, und öffnen Sie die Datei beide Male mit encoding="utf-8".

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    json.dump(data, f) schreibt in eine offene Datei; json.load(f) liest aus einer.

  2. Hinweis 2

    Übergeben Sie json.dump indent=2, dann steht jedes Element in einer eigenen Zeile, zwei Leerzeichen pro Ebene.

  3. Hinweis 3

    In save_json: json.dump(data, f, indent=2). In load_json: return json.load(f).

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

import json


def save_json(path: str, data: object) -> None:
    with open(path, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2)


def load_json(path: str) -> object:
    with open(path, encoding="utf-8") as f:
        return json.load(f)


if __name__ == "__main__":
    save_json("demo.json", {"tasks": ["write lesson"], "done": False})
    print(load_json("demo.json"))
Auf dem eigenen Computer ausführen

Installieren Sie Python 3.14 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.py

import json


def save_json(path: str, data: object) -> None:
    with open(path, "w", encoding="utf-8") as f:
        f.write(str(data))


def load_json(path: str) -> object:
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


if __name__ == "__main__":
    save_json("demo.json", {"tasks": ["write lesson"], "done": False})
    print(load_json("demo.json"))

test_main.py

import json

from main import load_json, save_json


def test_round_trip():
    """Ein Dictionary mit Liste, None und True kommt gleich zurück"""
    data = {"tasks": ["a", "b"], "due": None, "done": True, "city": "München"}
    save_json("t1.json", data)
    got = load_json("t1.json")
    assert got == data, f"load_json gab {got!r} zurück, erwartet war {data!r}"


def test_real_json():
    """Die Datei enthält JSON, das andere Programme lesen können"""
    save_json("t2.json", {"done": False})
    with open("t2.json", encoding="utf-8") as f:
        text = f.read()
    try:
        json.loads(text)
    except ValueError:
        assert False, f"die Datei enthält kein gültiges JSON: {text!r}"
    assert "false" in text, f"die Datei enthält {text!r}: False muss als false geschrieben sein"


def test_indent():
    """Die Datei ist mit 2 Leerzeichen eingerückt"""
    save_json("t3.json", {"a": 1})
    with open("t3.json", encoding="utf-8") as f:
        text = f.read()
    assert text == '{\n  "a": 1\n}', f"die Datei enthält {text!r}, erwartet war eine Einrückung mit 2 Leerzeichen"

Unter macOS und Linux tippen Sie python3, wo in diesen Befehlen python steht, wie in der ersten Lektion.

Programm ausführen:

python main.py

Prüfungen ausführen (learnrun.py muss im selben Ordner liegen):

python learnrun.py test
learnrun.py herunterladen

Übung 2 von 2

Wer wohnt in dieser Stadt?

contacts.json (zweiter Reiter) enthält eine Liste von Kontakten, jeder ein Dictionary mit name und city. Lesen Sie mit input() eine Stadt, laden Sie die Datei mit json.load und geben Sie die Namen aller Personen in dieser Stadt alphabetisch aus, einen pro Zeile. Wohnt dort niemand, geben Sie nobody in und die Stadt aus, zum Beispiel nobody in Rome.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    with open("contacts.json", encoding="utf-8") as f: contacts = json.load(f) liefert eine Liste von Dictionaries.

  2. Hinweis 2

    Jeder Kontakt ist ein Dictionary, contact["city"] und contact["name"] lesen also seine Felder.

  3. Hinweis 3

    sorted(contact["name"] for contact in contacts if contact["city"] == city) liefert die Namen sortiert; eine leere Liste ist falsch.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

import json

city = input()
with open("contacts.json", encoding="utf-8") as f:
    contacts = json.load(f)

names = sorted(contact["name"] for contact in contacts if contact["city"] == city)
if names:
    for name in names:
        print(name)
else:
    print("nobody in", city)
Auf dem eigenen Computer ausführen

Installieren Sie Python 3.14 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.py

import json

city = input()
# Load contacts.json and print the names of the contacts in this city.
print("nobody in", city)

test_main.py

from learnrun import run_main


def names_in(city):
    return run_main(city + "\n").strip().splitlines()


def test_berlin():
    """Berlin listet Ada und Linus, sortiert"""
    got = names_in("Berlin")
    assert got == ["Ada", "Linus"], f"für Berlin gab das Programm {got!r} aus"


def test_munich():
    """München listet einen Namen"""
    got = names_in("München")
    assert got == ["Grace"], f"für München gab das Programm {got!r} aus"


def test_nobody():
    """Eine Stadt ohne Kontakte ergibt nobody in …"""
    got = names_in("Rome")
    assert got == ["nobody in Rome"], f"für Rome gab das Programm {got!r} aus"

contacts.json

[
  {"name": "Linus", "city": "Berlin"},
  {"name": "Grace", "city": "München"},
  {"name": "Ada", "city": "Berlin"}
]

Unter macOS und Linux tippen Sie python3, wo in diesen Befehlen python steht, wie in der ersten Lektion.

Programm ausführen:

python main.py

Prüfungen ausführen (learnrun.py muss im selben Ordner liegen):

python learnrun.py test
learnrun.py herunterladen

Häufige Fehler

Ein Set speichern

import json

tags = {"work", "home"}
print(json.dumps(tags))

Was Python ausgibt

TypeError: Object of type set is not JSON serializable

Warum, und die Lösung

JSON kennt keine Sets. Wandeln Sie das Set vor dem Speichern in eine Liste um, am besten sortiert, damit die Datei jedes Mal gleich aussieht: json.dumps(sorted(tags)). Nach dem Laden macht set(...) wieder ein Set daraus.

JSON mit einfachen Anführungszeichen schreiben

import json

data = json.loads("{'name': 'Ada'}")

Was Python ausgibt

json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Warum, und die Lösung

Strings und Schlüssel brauchen in JSON doppelte Anführungszeichen; einfache sind Python, nicht JSON. Schreiben Sie den Text als '{"name": "Ada"}', oder besser: Lassen Sie json.dumps ihn erzeugen, statt JSON von Hand zu tippen.

json.load einen Dateinamen übergeben

import json

data = json.load("data.json")

Was Python ausgibt

AttributeError: 'str' object has no attribute 'read'

Warum, und die Lösung

json.load erwartet eine offene Datei und ruft .read() auf dem auf, was Sie übergeben. Öffnen Sie die Datei zuerst: with open("data.json", encoding="utf-8") as f: data = json.load(f). json.loads ist die Funktion, die einen String nimmt, und zwar JSON-Text, keinen Dateinamen.

Python im Browser: Pyodide 314.0.7, MPL-2.0. Lizenz und Quellcode

Abschlussquiz

5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.

Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.

Problem melden

Etwas ist falsch oder unklar? Beschreiben Sie es kurz, dann wird es geprüft und korrigiert.

#

Mindestens 20 Zeichen.

Nur, wenn Sie eine Antwort wünschen.

Kernideen

Text hinein, Text heraus: dumps und loads

JSON ist ein Textformat für Daten, das fast jede Sprache lesen kann. json.dumps(data) macht aus Python-Daten einen JSON-String, json.loads(text) macht aus einem JSON-String wieder Python-Daten. Der Text sieht aus wie Python, mit Unterschieden: Strings stehen immer in doppelten Anführungszeichen, aus True und False werden true und false, aus None wird null. json.dumps(data, indent=2) verteilt den Text auf mehrere Zeilen, zwei Leerzeichen pro Ebene; das liest und vergleicht sich leichter.

Dateien: dump und load

json.dump(data, f) schreibt den JSON-Text direkt in eine zum Schreiben geöffnete Datei, und json.load(f) liest eine ganze zum Lesen geöffnete Datei und liefert die Daten. Achten Sie auf die Namen: Ohne s nehmen sie ein Dateiobjekt, mit s nehmen oder liefern sie einen String. Öffnen Sie JSON-Dateien in beide Richtungen mit encoding="utf-8". Das übliche Muster: Datei laden, Liste oder Dictionary im Speicher ändern, mit "w" wieder speichern.

Was JSON fassen kann

JSON kennt Objekte, Arrays, Strings, Zahlen, true, false und null. Speichern lassen sich also Dictionaries, Listen, Tupel, Strings, ints, floats, True, False und None, sonst nichts. Ein Tupel wird als Array gespeichert und kommt als Liste zurück. Schlüssel sind in JSON immer Strings, aus {1: "a"} wird also {"1": "a"}. Ein Set oder ein Objekt einer eigenen Klasse löst TypeError aus: Object of type set is not JSON serializable. Wandeln Sie vorher um, etwa mit sorted(my_set).

Quellen

Zuletzt geprüft am 29. September 2026