Wozu das super()-__init__(**kwargs)?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Die HangmanGame-Instanz stellt auch ein BoxLayout dar (da sie deren Eigenschaften und Verhaltensweisen erbt). Falls du nun beim Erstellen der HangmanGame-Instanz Eigenschaften vordefinieren möchtest, die durch die Basisklasse umgesetzt werden, wird das durch die Konstruktorimplementation auch unterstützt.

Vergleiche:

class HangmanGame(BoxLayout):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)

game = HangmanGame(spacing=10)

mit:

class HangmanGame(BoxLayout):
  def __init__(self, **kwargs):
    pass

game = HangmanGame(spacing=10)

Im ersten Fall kann die Funktionalität der Basisklasse genutzt werden. Die Kindelemente des Layouts erhalten einen Abstand zueinander.

Im zweiten Fall hingegen wird der Parameter nicht weiterverarbeitet, also ignoriert.

CodeSnake 
Fragesteller
 17.05.2023, 19:44

Also wird der Wert sonst ignoriert? Ganz sicher?

Aber kann man das nicht auch bei dem zweiten Beispiel in der __init__() Methode der aktuellen Klasse machen? Ich frage nur um mich zu vergewissern.

0
regex9  17.05.2023, 20:01
@CodeSnake
Also wird der Wert sonst ignoriert? Ganz sicher?

Probier es aus.

Aber kann man das nicht auch bei dem zweiten Beispiel in der __init__() Methode der aktuellen Klasse machen?

Du kannst in der __init__-Methode von HangmanGame die Properties setzen.

Beispiel:

class HangmanGame(BoxLayout):
  def __init__(self, **kwargs):
    if "spacing" in kwargs:
      self.spacing = kwargs["spacing"]

Das bedeutet aber nicht, dass der Wert deswegen sofort genutzt wird. Wenn der Basiskonstruktor neben dem Setzen von Attributen noch bestimmte Aktionen durchführt, müsstest du diese erst nachbilden.

Einfacheres Beispiel:

class Animal:
  def __init__(self, **kwargs):
    if "name" in kwargs:
      self.name = kwargs["name"]
      print(self.name)

class Lion(Animal):
  def __init__(self, **kwargs):
    super().__init__(**kwargs)

class Dolphin(Animal):
  def __init__(self, **kwargs):
    if "name" in kwargs:
      self.name = kwargs["name"]

leo = Lion(name="Leo")
flipper = Dolphin(name="Flipper")

Der Basiskonstruktor hat eine Extralogik implementiert, die die Ausgabe des Namens bewirkt. Der Löwe profitiert davon, da er einfach nur den Basiskonstruktor aufruft. Der Delphin hingegen setzt nur den Namen.

In diesem Fall mag das noch nicht so problematisch zu sein. Den einen print-Aufruf könnte man in Dolphin auch noch ergänzen.

Bei GUI-Komponenten hingegen kommt es durchaus häufiger vor, dass der Konstruktor mehrere Aktionen durchführt, die z.B. das Zeichnen der Komponente triggern oder Events registrieren. Was alles im Konstruktor geschieht, müsstest du ebenso erst einmal in Erfahrung bringen.

1
CodeSnake 
Fragesteller
 20.05.2023, 08:53
@regex9

In dieser Antwort und in deiner neuesten ist aber ein Widerspruch. Hier sagen Sie:

Du kannst in der __init__-Methode von HangmanGame die Properties setzen. Das bedeutet aber nicht, dass der Wert deswegen sofort genutzt wird. Wenn der Basiskonstruktor neben dem Setzen von Attributen noch bestimmte Aktionen durchführt, müsstest du diese erst nachbilden.

In deiner neuesten Antwort sagten Sie aber immer, dass die Instanzvariablen aus dem Konstruktor gar nicht übergeben werden müssten, da die Basisklasse schon darauf zugreifen könne.

0
CodeSnake 
Fragesteller
 19.05.2023, 21:59

Aber wenn man dann die Argumente als kwargs an den Konstruktor von der HangmanGame Klasse übergibt, dann kann der Konstruktor der Basisklasse doch schon darauf zugreifen. Wozu dann das super()?

0
regex9  19.05.2023, 23:28
@CodeSnake

Wieso erhalte ich beim Beispiel meines letzten Kommentars dann keine Ausgabe "Flipper"?

0
CodeSnake 
Fragesteller
 20.05.2023, 08:45
@regex9

Das weiß ich nicht. Aber meine Frage lautet:

Aber wenn man dann die Argumente als kwargs an den Konstruktor von der HangmanGame Klasse übergibt, dann kann der Konstruktor der Basisklasse doch schon darauf zugreifen. Wozu dann das super()?

Wenn ich den Code ausführe und kein Flipper als Ausgabe erhalte, dann weiß ich, dass ich das super() brauche. Warum aber nicht.

0

Damit beim instanziieren Deiner Klaswe Argumente für die Basisklasse durchgereicht werden - andernfalls müßtest Du deren Funktionalität replizieren, was das Konzept der Vererbung ad absurdum führen würde.