Kapitel 13 • Schulabgleich 14.0

Datei-Persistenz: JSON & CSV 💾📁

Lerne, wie du Daten dauerhaft auf der Festplatte speicherst, Objekte mit to_dict() und from_dict() serialisierst und Tabellen als CSV exportierst.

1. Warum brauchen wir Persistenz? (Die Tagebuch-Analogie)

Bislang haben alle unsere Programme ihre Daten nur im Arbeitsspeicher (RAM) gehalten. Das Problem: Sobald das Python-Programm beendet wird oder der Strom ausfällt, ist der gesamte RAM blitzschnell gelöscht!

📓 Die Tagebuch-Analogie:
Der Arbeitsspeicher (RAM) ist wie dein Kurzzeitgedächtnis: blitzschnell, aber nach dem Schlafen (Programmende) ist alles weg. Die Festplatte (SSD) ist dein Tagebuch / Notizbuch: Was du einmal mit Tinte hineingeschrieben hast, bleibt auch Jahre später noch genau so stehen!

Der goldene Standard: Dateien sicher öffnen mit with open()

Kontext-Manager mit open()
# 'w' = Write (Schreiben / Überschreiben)
# 'r' = Read (Lesen)
# 'a' = Append (Am Ende anhängen)

with open("notizen.txt", "w", encoding="utf-8") as datei:
    datei.write("Hallo Welt mit Umlauten: ä, ö, ü!\n")
# Hier wird die Datei automatisch und sicher geschlossen – selbst wenn ein Fehler auftritt!

2. JSON vs. CSV: Welches Format für welchen Zweck?

Kriterium JSON (JavaScript Object Notation) CSV (Comma-Separated Values)
Ideal für... Komplexe, verschachtelte Objekte & Savegames Flache Tabellen (Excel, Google Sheets)
Verschachtelung Ja (Listen von Objekten mit Unter-Listen) Nein (nur Zeilen und Spalten)
Python-Modul import json import csv
Hauptbefehle json.dump() / json.load() csv.DictWriter / csv.DictReader

3. Objekt-Serialisierung: to_dict() und from_dict()

Ein Python-Klassenobjekt (z.B. Spieler) kann nicht direkt als reiner Text gespeichert werden. Daher übersetzen wir das Objekt in ein einfaches Dictionary (Serialisierung) und bauen es beim Laden wieder als echtes Objekt zusammen (Deserialisierung).

Serialisierungsmuster in Klassen
class Spieler:
    def __init__(self, name: str, level: int, punkte: int):
        self.name = name
        self.level = level
        self.punkte = punkte

    # 1. In Dictionary umwandeln (zum Speichern)
    def to_dict(self) -> dict:
        return {
            "name": self.name,
            "level": self.level,
            "punkte": self.punkte
        }

    # 2. Aus Dictionary neues Objekt instanziieren (beim Laden)
    @classmethod
    def from_dict(cls, daten: dict) -> 'Spieler':
        return cls(
            name=daten["name"],
            level=daten["level"],
            punkte=daten["punkte"]
        )

Speichern und Laden mit JSON

JSON Speichern und Laden
import json

# Speichern:
with open("savegame.json", "w", encoding="utf-8") as f:
    json.dump(spieler.to_dict(), f, indent=4, ensure_ascii=False)

# Laden:
with open("savegame.json", "r", encoding="utf-8") as f:
    daten = json.load(f)
    geladener_spieler = Spieler.from_dict(daten)

4. 🎯 Deine Aufgaben in aufgabe.py

Öffne die Datei 13_persistenz_json_und_csv/aufgabe.py und vervollständige das Savegame-System:

💡 Lösungshinweise (Aufklappen bei Bedarf)

🔍 Tipp zum JSON-Speichern
daten = {
    "titel": self.titel,
    "spieler": [s.to_dict() for s in self.spieler_liste]
}
with open(dateipfad, "w", encoding="utf-8") as f:
    json.dump(daten, f, indent=4, ensure_ascii=False)
🔍 Tipp zum CSV-Export
feldnamen = ["name", "level", "punkte", "inventar_anzahl"]
with open(dateipfad, "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=feldnamen)
    writer.writeheader()
    for s in self.spieler_liste:
        writer.writerow({
            "name": s.name,
            "level": s.level,
            "punkte": s.punkte,
            "inventar_anzahl": len(s.inventar)
        })

5. 🧪 Lösung überprüfen

Führe im Terminal im Ordner 13_persistenz_json_und_csv folgenden Befehl aus:

Terminal
python3 test_aufgabe.py