514 Stimmen

Wie ruft man den Superkonstruktor in Python auf?

klasse A:
    def __init__(self):
        print("Welt")

klasse B(A):
    def __init__(self):
       print("Hallo")

B()  # Ausgabe: Hallo

In allen anderen Sprachen, mit denen ich gearbeitet habe, wird der Super-Konstruktor implizit aufgerufen. Wie ruft man ihn in Python auf? Ich würde erwarten super(self), aber das funktioniert nicht.

1 Stimmen

Sie sollten betonen, dass Sie eine Antwort möchten, die den abgeleiteten Klassennamen nicht verwendet. z.B. (Pseudocode): super().__init__(args...)

1 Stimmen

Du solltest Aidan Gomez Antwort akzeptieren. Es würde uns viel Zeit sparen, da sie eine Antwort sowohl in Python 2 als auch in 3 hat.

1 Stimmen

Python 2 wird nicht mehr offiziell unterstützt. Auch seine Antwort kam 5 Jahre später.

454voto

Aidan Gomez Punkte 7509

Im Einklang mit den anderen Antworten gibt es mehrere Möglichkeiten, die Methoden der Oberklasse aufzurufen (einschließlich des Konstruktors), jedoch wurde der Prozess in Python 3 vereinfacht:

Python 3

class A(object):
    def __init__(self):
        print("world")

class B(A):
    def __init__(self):
        print("hello")
        super().__init__()

Python 2

In Python 2 müssen Sie die etwas ausführlichere Version super(, self) aufrufen, was äquivalent zu super() ist, wie es in der Dokumentation angegeben ist.

class A(object):
    def __init__(self):
        print "world"

class B(A):
    def __init__(self):
        print "hello"
        super(B, self).__init__()

378voto

super() gibt ein elterliches Objekt in neuen Style-Klassen zurück:

class A(object):
    def __init__(self):
        print("Welt")

class B(A):
    def __init__(self):
        print("Hallo")
        super(B, self).__init__()

B()

88 Stimmen

Nur aus Neugierde, warum müssen bei super(B, self) sowohl B als auch self genannt werden? Ist das nicht überflüssig? Sollte self nicht bereits eine Referenz zu B enthalten?

121 Stimmen

Nein, denn self könnte tatsächlich eine Instanz von C sein, einem Kind von B.

1 Stimmen

Was ist, wenn B(A, AA)? Ich sehe, dass super(B, self) A zurückgibt, aber wie bekommst du dann AA?

53voto

Gabe Punkte 82268

Mit den alten Klassen im Python 2.x-Stil sähe es so aus:

class A: 
 def __init__(self): 
   print "Welt" 

class B(A): 
 def __init__(self): 
   print "Hallo" 
   A.__init__(self)

6 Stimmen

@kdbanman: Dies funktioniert mit neuen Klassen, aber einer der Gründe, neue Klassen zu verwenden, besteht darin, es nicht auf diese Weise tun zu müssen. Du kannst super verwenden und musst die Klasse, von der du erbst, nicht direkt benennen.

0 Stimmen

@Gabe Das ist einer der unwichtigsten Gründe, um super zu verwenden.

37voto

Daniel Stutzbach Punkte 69710

Ein Weg besteht darin, den Konstruktor von A aufzurufen und self als Argument zu übergeben, wie folgt:

class B(A):
    def __init__(self):
        A.__init__(self)
        print "Hallo"

Der Vorteil dieses Stils ist, dass er sehr klar ist. Er ruft den Initialisierer von A auf. Der Nachteil ist, dass er die Vererbung in Form von Diamanten nicht sehr gut handhabt, da Sie möglicherweise den Initialisierer der gemeinsamen Basisklasse zweimal aufrufen.

Ein anderer Weg ist die Verwendung von super(), wie es andere gezeigt haben. Bei einfacher Vererbung tut es im Grunde dasselbe wie das Aufrufen des Initialisierers des Elternteils.

Allerdings ist super() unter der Oberfläche ziemlich kompliziert und kann in Situationen mit mehrfacher Vererbung manchmal gegen die Intuition sein. Auf der positiven Seite kann super() dazu verwendet werden, Vererbung in Form von Diamanten zu handhaben. Wenn Sie die genauen Einzelheiten davon erfahren möchten, was super() macht, ist die beste Erklärung, die ich für die Funktionsweise von super() gefunden habe, hier (obwohl ich nicht unbedingt die Meinungen des Artikels befürworte).

1 Stimmen

Muss A's Konstruktor so aufgerufen werden, wenn er kein Argument (ignorieren Sie self) annimmt? Ich meine, der Code funktioniert einwandfrei ohne die Zeile A.__init__(self).

0 Stimmen

@RedFloyd Es hängt davon ab, was A.__init__ tatsächlich macht. Es könnte interne Attribute auf konstante Weise initialisieren (self.stuff = [], z. B.), was dazu führen könnte, dass Ihre Instanz von B sich nicht richtig verhält, wenn Sie A.__init__ nicht aufrufen.

20voto

gal007 Punkte 6307

Nur um ein Beispiel mit Parametern hinzuzufügen:

class B(A):
    def __init__(self, x, y, z):
        A.__init__(self, x, y)

Angenommen, es gibt eine abgeleitete Klasse B, die erfordert, dass die Variablen x, y, z definiert sind, und eine Superklasse A, die erfordert, dass x, y definiert sind, dann können Sie die statische Methode init der Superklasse A aufrufen mit einem Verweis auf die aktuelle Subklasseninstanz (self) und dann die Liste der erwarteten Argumente.

0 Stimmen

Dies ist eine korrektere Antwort, da die Klasse, die als super() gerendert wird, sich ändern kann ... dies macht klarer, welchen Konstruktor Sie aufrufen möchten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X