Aufwärmen · Aufgabe 1 von 7
// 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.
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
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}))Ü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)Ü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"})))Üben · Aufgabe 5 von 7
Ordnen Sie jedem Python-Wert zu, was json.dumps dafür schreibt.
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)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.pyAusgabe
[
{
"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
Hinweis 1
json.dump(data, f) schreibt in eine offene Datei; json.load(f) liest aus einer.
Hinweis 2
Übergeben Sie json.dump indent=2, dann steht jedes Element in einer eigenen Zeile, zwei Leerzeichen pro Ebene.
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.pyPrüfungen ausführen (learnrun.py muss im selben Ordner liegen):
python learnrun.py testlearnrun.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
Hinweis 1
with open("contacts.json", encoding="utf-8") as f: contacts = json.load(f) liefert eine Liste von Dictionaries.
Hinweis 2
Jeder Kontakt ist ein Dictionary, contact["city"] und contact["name"] lesen also seine Felder.
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.pyPrüfungen ausführen (learnrun.py muss im selben Ordner liegen):
python learnrun.py testlearnrun.py herunterladenHä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 serializableWarum, 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.