Kurs
Du hast wahrscheinlich schon von verschachtelten Funktionen in Python gehört. Wenn dir das etwas sagt, sind innere/verschachtelte Klassen kein Hexenwerk. Hier schauen wir uns Neues rund um innere bzw. verschachtelte Klassen an.
1. Innere bzw. verschachtelte Klassen
Eine innere bzw. verschachtelte Klasse wird innerhalb einer anderen Klasse definiert. So sieht die Struktur von inneren bzw. verschachtelten Klassen aus.
## outer class
class Outer:
## inner class
class Inner:
pass
## multilevel inner class
class InnerInner:
pass
## another inner class
class _Inner:
pass
## ...
pass
Code aus diesem Tutorial online ausführen und bearbeiten
Code ausführen2. Warum innere Klassen?
-
Logisches Gruppieren mehrerer Klassen. Angenommen, du hast die Klassen Car und Engine. Jedes Car braucht einen Engine. Ein Engine wird aber nicht ohne ein Car verwendet. Also machst du den Engine zur inneren Klasse von Car. Das spart Code und hält ihn zusammen.
-
Kapselung: Mit verschachtelten Klassen kannst du Implementierungsdetails vor der Außenwelt verbergen.
-
Bessere Lesbarkeit: Die Klassen stehen in engem Zusammenhang. Du musst sie nicht im Code zusammensuchen – sie stehen beieinander.
Innere bzw. verschachtelte Klassen gehören nicht zu den am häufigsten genutzten Features in Python. Sie können aber sehr hilfreich sein, um Code sauber zu strukturieren. Mit inneren bzw. verschachtelten Klassen lässt sich der Code übersichtlich organisieren.
3. Innere Klassen implementieren
Die Implementierung von inneren bzw. verschachtelten Klassen ist unkompliziert. Die Grundstruktur findest du hier.
Auf die innere Klasse in der äußeren Klasse greifst du über self zu. So kannst du schnell eine Instanz der inneren Klasse erzeugen und in der äußeren Klasse nutzen. Umgekehrt kannst du aus einer inneren Klasse nicht direkt auf die äußere Klasse zugreifen. Schauen wir uns ein Beispiel an.
class Outer:
"""Outer Class"""
def __init__(self):
## instantiating the 'Inner' class
self.inner = self.Inner()
def reveal(self):
## calling the 'Inner' class function display
self.inner.inner_display("Calling Inner class function from Outer class")
class Inner:
"""Inner Class"""
def inner_display(self, msg):
print(msg)
Jetzt erzeugst du eine Instanz der Outer-Klasse und rufst ihre Methode reveal() auf, um die Methode inner_display() der Inner-Klasse auszuführen.
## creating an instance of the 'Outer' class
outer = Outer()
## calling the 'reveal()' method
outer.reveal()
Calling Inner class function from Outer class
Es geht auch anders, um auf die innere Klasse zuzugreifen – etwas weniger effizient, aber möglich.
Outer().Inner().inner_display("Calling the Inner class method directly")
Calling the Inner class method directly
Was, wenn du eine Instanz der inneren Klasse außerhalb der äußeren Klasse erzeugen willst? Geht das? Ja – so erstellst du eine Instanz der inneren Klasse außerhalb der äußeren Klasse.
outer = Outer()
## instantiating the inner class
inner = outer.Inner() ## inner = Outer().Inner() or inner = outer.inner
inner.inner_display("Just Print It!")
Just Print It!
3.1. Mehrere innere Klassen
Eine Klasse kann mehr als eine innere Klasse enthalten. Wie oben beschrieben, ist die Umsetzung mehrerer innerer Klassen einfach.
class Outer:
"""Outer Class"""
def __init__(self):
## Instantiating the 'Inner' class
self.inner = self.Inner()
## Instantiating the '_Inner' class
self._inner = self._Inner()
def show_classes(self):
print("This is Outer class")
print(inner)
print(_inner)
class Inner:
"""First Inner Class"""
def inner_display(self, msg):
print("This is Inner class")
print(msg)
class _Inner:
"""Second Inner Class"""
def inner_display(self, msg):
print("This is _Inner class")
print(msg)
## ...
Der Zugriff funktioniert genauso wie zuvor. Ein Beispiel macht es anschaulich.
## instantiating the classes
## 'Outer' class
outer = Outer()
## 'Inner' class
inner = outer.Inner() ## inner = outer.inner or inner = Outer().Inner()
## '_Inner' class
_inner = outer._Inner() ## _inner = outer._outer or _inner = Outer()._Inner()
## calling the methods
outer.show_classes()
print()
## 'Inner' class
inner.inner_display("Just Print It!")
print()
## '_Inner' class
_inner.inner_display("Just Show It!")
This is Outer class
<__main__.Outer.Inner object at 0x0000021B37962048>
<__main__.Outer._Inner object at 0x0000021B37962160>
This is Inner class
Just Print It!
This is _Inner class
Just Show It!
3.2. Mehrstufige innere Klassen
Bei mehrstufigen inneren Klassen enthält eine innere Klasse wiederum eine Klasse, die zur vorherigen inneren Klasse gehört. Die Struktur dieser Hierarchie siehst du hier:
class Outer:
"""Outer Class"""
def __init__(self):
## instantiating the 'Inner' class
self.inner = self.Inner()
## instantiating the multilevel 'InnerInner' class
self.innerinner = self.inner.InnerInner()
def show_classes(self):
print("This is Outer class")
print(inner)
## inner class
class Inner:
"""First Inner Class"""
def __init__(self):
## instantiating the 'InnerInner' class
self.innerinner = self.InnerInner()
def show_classes(self):
print("This is Inner class")
print(self.innerinner)
## multilevel inner class
class InnerInner:
def inner_display(self, msg):
print("This is multilevel InnerInner class")
print(msg)
def inner_display(self, msg):
print("This is Inner class")
print(msg)
## ...
So instanzierst du eine mehrstufige innere Klasse.
outer = Outer()
inner = outer.Inner()
## this is 'InnerInner' class instance
innerinner = inner.InnerInner() ## innerinner = Outer().Inner().InnerInner()
## let's call its method inner_display
innerinner.inner_display("Just Print It!")
This is multilevel InnerInner class
Just Print It!
Fazit
Ich hoffe, das Konzept innerer Klassen ist jetzt klar. Zeit, mit verschachtelten Klassen zu experimentieren. Viel Spaß beim Coden :)
Wenn du mehr über Klassen lernen möchtest, schau dir DataCamps Python Object-Oriented Programming (OOP): Tutorial an.
Oder belege den DataCamp-Kurs Object-Oriented Programming in Python.