Kapitel 07 • Fortgeschrittenes OOP

Referenzen, Speicher & Stammbäume 🧠🌳

Verstehe, wie Python Objekte im Arbeitsspeicher verwaltet, was Aliasing bedeutet und baue einen echten Familienstammbaum.

1. Was ist eine Referenz? (Variablen sind Namensschilder)

Viele glauben, eine Variable sei eine Box, in der das Objekt direkt drinliegt. In Python ist das anders: Eine Variable ist in Wirklichkeit ein Zeiger (eine Referenz) auf einen Bereich im Arbeitsspeicher (RAM).

🏷️ Die Namensschild-Analogie:
Stelle dir ein Haus vor. Das Haus steht an einer festen Adresse. Die Variable ist nur ein Adresszettel. Wenn du schreibst b = a, baust du kein zweites Haus, sondern schreibst die gleiche Adresse einfach auf einen zweiten Zettel!

Das Phänomen: Was passiert bei b = a?

Beispiel: Listen-Referenzen (Aliasing)
liste_a = [1, 2, 3]
liste_b = liste_a     # liste_b zeigt auf GENAU DIESELBE Liste im Speicher!

liste_b.append(99)

print(liste_a)  # Ausgabe: [1, 2, 3, 99] <-- liste_a hat sich mitverändert!
⚠️ Vorsicht bei veränderlichen Objekten (Mutable vs. Immutable):
  • Mutable (veränderlich): Listen, Dictionaries, eigene Klassenobjekte. Wenn du sie an einer Stelle änderst, ändern sich alle Variablen, die darauf zeigen!
  • Immutable (unveränderlich): Zahlen (int, float), Texte (str), Tupel (tuple). Beim Ändern wird automatisch ein neues Objekt im Speicher erzeugt.

2. Der Unterschied zwischen == und is

In Python gibt es zwei Arten von Vergleichen:

Operator Bedeutung Frage im Hintergrund
== Wertegleichheit Haben beide Objekte denselben Inhalt?
is Identität Sind beide Variablen exakt dasselbe Objekt an derselben Speicheradresse?
x = [1, 2, 3]
y = [1, 2, 3]
z = x

print(x == y)  # True  (weil der Inhalt gleich ist)
print(x is y)  # False (zwei getrennte Listen im Speicher)
print(x is z)  # True  (z zeigt direkt auf dieselbe Liste wie x)

3. Praxisbeispiel: Der Familienstammbaum 🌳

Warum sind Referenzen so genial? Weil ein und dasselbe Objekt in vielen Beziehungen vorkommen kann. Eine Person namens Susi ist gleichzeitig die Mutter von Erika, das Kind von Fritz und die Schwester von Tom.

Stammbaum mit Klassen-Referenzen
class Person:
    def __init__(self, name: str, geburtsjahr: int):
        self.name: str = name
        self.geburtsjahr: int = geburtsjahr
        self.mutter: Person | None = None   # Referenz auf Mutter-Objekt
        self.vater: Person | None = None    # Referenz auf Vater-Objekt
        self.kinder: list[Person] = []      # Liste von Referenzen auf Kinder

    def mutter_setzen(self, mutter: 'Person') -> None:
        self.mutter = mutter
        if self not in mutter.kinder:
            mutter.kinder.append(self)

    def __str__(self) -> str:
        return f"{self.name} (*{self.geburtsjahr})"

4. 🎯 Deine Aufgaben in aufgabe.py

Öffne die Datei 07_referenzen_und_speicher/aufgabe.py und vervollständige die Stammbaum-Klasse:

💡 Lösungshinweise (Aufklappen bei Bedarf)

🔍 Tipp zu TODO 4 (Geschwister finden)

Gehe alle Kinder der Mutter und alle Kinder des Vaters durch. Achte darauf, dass du kind is not self prüfst, damit man nicht selbst als Geschwisterteil gelistet wird, und füge niemanden doppelt hinzu!

🔍 Tipp zu TODO 5 (Großeltern finden)
ge = []
if self.mutter:
    if self.mutter.mutter: ge.append(self.mutter.mutter)
    if self.mutter.vater: ge.append(self.mutter.vater)
if self.vater:
    if self.vater.mutter: ge.append(self.vater.mutter)
    if self.vater.vater: ge.append(self.vater.vater)
return ge

5. 🧪 Lösung überprüfen

Führe im Terminal im Ordner 07_referenzen_und_speicher folgenden Befehl aus:

Terminal
python3 test_aufgabe.py