Heim > Artikel > Backend-Entwicklung > Der Unterschied zwischen super() und __init__() in Python-Klassen
Die von super() und __init__() implementierten Funktionen sind bei der Einzelvererbung ähnlich
class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'creat A ', Base.__init__(self) class childB(Base): def __init__(self): print 'creat B ', super(childB, self).__init__() base = Base() a = childA() b = childB()
Ausgabeergebnis:
Base create creat A Base create creat B Base create
Der Unterschied besteht darin, dass Sie bei Verwendung der super()-Vererbung nicht explizit auf die Basisklasse verweisen müssen.
super() kann nur in Klassen neuen Stils verwendet werden
Ändern Sie die Basisklasse in eine Klasse im alten Stil, d. h. erben Sie keine Basisklasse
class Base(): def __init__(self): print 'Base create'
Bei der Ausführung wird beim Initialisieren von b ein Fehler gemeldet:
super(childB, self).__init__() TypeError: must be type, not classobj
Super ist nicht die übergeordnete Klasse, sondern die nächste Klasse in der Vererbungssequenz
Im Falle einer Mehrfachvererbung entspricht die Vererbungsreihenfolge super() der Rückgabe der nächsten Klasse in der Vererbungsreihenfolge anstelle der übergeordneten Klasse, ähnlich wie bei dieser Funktion:
def super(class_name, self): mro = self.__class__.mro() return mro[mro.index(class_name) + 1]
mro() wird verwendet, um die Vererbungsreihenfolge von Klassen zu ermitteln.
Zum Beispiel:
class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'enter A ' # Base.__init__(self) super(childA, self).__init__() print 'leave A' class childB(Base): def __init__(self): print 'enter B ' # Base.__init__(self) super(childB, self).__init__() print 'leave B' class childC(childA, childB): pass c = childC() print c.__class__.__mro__
Die Ausgabeergebnisse lauten wie folgt:
enter A enter B Base create leave B leave A (<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
supder ist nicht mit der übergeordneten Klasse verbunden, daher ist die Ausführungsreihenfolge A –> B –> –>Basis
Der Ausführungsprozess ist äquivalent zu: Beim Initialisieren von childC() wird zuerst super(childA, self).__init__() im Konstruktor von childA aufgerufen, super(childA, self) kehrt nach childA in der Vererbungssequenz von zurück die aktuelle Klasse A-Klasse childB; dann childB().__init()__ ausführen und in dieser Reihenfolge fortfahren.
Wenn Sie bei der Mehrfachvererbung super(childA, self).__init__() in childA() durch Base.__init__(self) ersetzen, wird nach der Vererbung von childA direkt zur Basisklasse und childB gesprungen wird übersprungen:
enter A Base create leave A (<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
Wie aus der super()-Methode ersichtlich ist, kann der erste Parameter von super() der Name einer beliebigen Klasse in der Vererbungskette sein,
Wenn es sich selbst ist, erbt es der Reihe nach die nächste Klasse
Wenn es sich um die vorherige Klasse in der Vererbungskette handelt, wird sie unendlich oft wiederholt.
Wenn es sich um eine spätere Klasse in der Vererbungskette handelt, werden die Klassen zwischen der Vererbungskettenzusammenfassung selbst und der eingehenden Klasse ignoriert;
Wenn beispielsweise „super“ in „childA()“ in „super(childC, self).init()“ geändert wird, führt das Programm eine unendliche Rekursion durch.Zum Beispiel:
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() RuntimeError: maximum recursion depth exceeded while calling a Python objectsuper() kann wiederholte Aufrufe vermeiden
Wenn ChildA auf Base basiert, erbt ChildB ChildA und Base, und wenn ChildB die __init__()-Methode von Base aufrufen muss, wird __init__() zweimal ausgeführt:
class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'enter A ' Base.__init__(self) print 'leave A' class childB(childA, Base): def __init__(self): childA.__init__(self) Base.__init__(self) b = childB()Bases __init__()-Methode wird zweimal ausgeführt
enter A Base create leave A Base createDurch die Verwendung von super() können wiederholte Aufrufe vermieden werden
class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'enter A ' super(childA, self).__init__() print 'leave A' class childB(childA, Base): def __init__(self): super(childB, self).__init__() b = childB() print b.__class__.mro() enter A Base create leave A [<class '__main__.childB'>, <class '__main__.childA'>, <class '__main__.Base'>, <type 'object'>]Das Obige ist der vom Herausgeber eingeführte Unterschied zwischen super() und __init__(). Ich hoffe, er wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht Sie rechtzeitig. Ich möchte mich auch bei Ihnen allen für Ihre Unterstützung der Script House-Website bedanken!