Der Unterschied zwischen super() und __init__() in Python-Klassen

WBOY
Freigeben: 2016-12-05 13:27:14
Original
1384 Leute haben es durchsucht

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()
Nach dem Login kopieren

Ausgabeergebnis:

Base create
creat A Base create
creat B Base create
Nach dem Login kopieren

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'
Nach dem Login kopieren

Bei der Ausführung wird beim Initialisieren von b ein Fehler gemeldet:

super(childB, self).__init__()
TypeError: must be type, not classobj
Nach dem Login kopieren

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]
Nach dem Login kopieren

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__
Nach dem Login kopieren

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'>)
Nach dem Login kopieren

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'>)
Nach dem Login kopieren

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 object
Nach dem Login kopieren

super() 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()
Nach dem Login kopieren

Bases __init__()-Methode wird zweimal ausgeführt

enter A 
Base create
leave A
Base create
Nach dem Login kopieren

Durch 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'>]
Nach dem Login kopieren
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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage