Frage

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

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

B()  # output: hello

In allen anderen Sprachen, die ich mit dem Superkonstruktor zusammengearbeitet habe, wird implizit aufgerufen. Wie ruft man es in Python auf? Ich würde erwarten super(self) Aber das funktioniert nicht.

War es hilfreich?

Lösung

super() Gibt ein übergeordnetes Objekt zurück in Neustilklassen:

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

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

B()

Andere Tipps

In Übereinstimmung mit den anderen Antworten gibt es mehrere Möglichkeiten, Superklassenmethoden (einschließlich des Konstruktors) aufzurufen. In Python-3.x wurde jedoch der Prozess vereinfacht:

Python-2.x

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

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

Python-3.x

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

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

super() ist jetzt gleichbedeutend mit super(<containing classname>, self) wie per Die Dokumente.

Mit Python 2.x-Klassen im alten Stil wäre es Folgendes:

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

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

Eine Möglichkeit besteht darin, den Konstruktor von A zu nennen und zu bestehen self Als Argument, wie so:

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

Der Vorteil dieses Stils ist, dass er sehr klar ist. Es nennt den Initialiser von A. Der Nachteil ist, dass es nicht sehr gut mit dem diamantförmigen Vererbung umgeht, da Sie möglicherweise den Initialiser der gemeinsamen Basisklasse zweimal nennen.

Eine andere Möglichkeit besteht darin, Super () zu verwenden, wie andere gezeigt haben. Für Single-Ineritance ist es im Grunde dasselbe wie Sie den Initialiser des Elternteils aufrufen können.

Super () ist jedoch ein bisschen komplizierter unter dem Haus und kann in mehreren Vererbungssituationen manchmal kontraintuitiv sein. Auf der positiven Seite kann Super () verwendet werden, um mit dem Diamant-förmigen Vererbung umzugehen. Wenn Sie das Zusammenspiel dessen wissen möchten, was Super () tut, ist die beste Erklärung, die ich dafür gefunden habe, wie Super () funktioniert hier (Obwohl ich nicht unbedingt die Meinungen dieses Artikels unterstütze).

Kurze Antwort

super(DerivedClass, self).__init__()

Lange Antwort

Was macht super() tun?

Es nimmt den festgelegten Klassennamen, findet seine Basisklassen (Python erlaubt mehrere Vererbung) und sucht nach der Methode (sucht nach der Methode (__init__ in diesem Fall) in jedem von ihnen von links nach rechts. Sobald es eine Methode zur Verfügung findet, wird sie anrufen und die Suche beenden.

Wie nenne ich Init aller Basisklassen?

Oben funktioniert, wenn Sie nur eine Basisklasse haben. Python erlaubt jedoch mehrere Vererbung und Sie möchten möglicherweise sicherstellen, dass alle Basisklassen ordnungsgemäß initialisiert werden. Dazu sollten Sie jeden Basisklassen -Anruf init:

class Base1:
  def __init__():
    super(Base1, self).__init__()

class Base2:
  def __init__():
    super(Base2, self).__init__()

class Derived(Base1, Base2):
  def __init__():
    super(Derived, self).__init__()

Was ist, wenn ich vergesse, Init für Super anzurufen?

Der Konstruktor (__new__) wird in einer Kette aufgerufen (wie in C ++ und Java). Sobald die Instanz erstellt wurde, ist nur der Initialiser dieser Instanz (__init__) wird genannt, ohne implizite Kette zu seiner Superklasse.

Nur um ein Beispiel mit Parametern hinzuzufügen:

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

Bei einer abgeleiteten Klasse B, bei der die Variablen x, y, z definiert werden müssen, und eine Superklasse A, für die x, y definiert werden muss, können Sie die statische Methode aufrufen drin der Superklasse A unter Bezugnahme auf die aktuelle Unterklasse -Instanz (Selbst) und dann die Liste der erwarteten Argumente.

Ich verwende die folgende Formel, die frühere Antworten erweitert:

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

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

B()

Auf diese Weise müssen Sie den Namen der Klasse im Anruf nicht wiederholen super. Es kann nützlich werden, wenn Sie eine große Anzahl von Klassen codieren und Ihren Code in den Initialiser -Methoden unabhängig vom Klassennamen erstellen möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top