Heim > Backend-Entwicklung > Python-Tutorial > Detaillierte Erklärung der super()-Methode in Python

Detaillierte Erklärung der super()-Methode in Python

爱喝马黛茶的安东尼
Freigeben: 2019-08-22 17:27:13
nach vorne
2411 Leute haben es durchsucht

Detaillierte Erklärung der super()-Methode in Python

1. Rufen Sie die übergeordnete Klassenmethode separat auf

Anforderung: Schreiben Sie eine Klasse und dann eine Unterklasse und verwenden Sie die Unterklasse, um Methode 1 der übergeordneten Klasse aufzurufen.

Verwenden Sie Methode 1 zum Ausdrucken: Fetter Chef, kommen Sie und packen Sie Betelnüsse ein.

Schreiben Sie dann zunächst eine Elternklasse des Fat Boss und führen Sie diese aus:

class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('FatFather的name是%s' % self.name)
        print('FatFather的init调用结束')
def main():
    ff = FatFather("胖子老板的父亲")
Nach dem Login kopieren

Führen Sie den Init-Konstruktor der Fat Boss-Elternklasse wie folgt aus:

if __name__ == "__main__":
    main()
FatFather的init开始被调用
FatFather的name是胖子老板的父亲
FatFather的init调用结束
Nach dem Login kopieren

Okay, dann Schreiben wir eine Unterklasse, nämlich die Fat Boss-Klasse, die die obige Klasse erbt.

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')
# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        FatFather.__init__(self, name)  # 直接调用父类的构造方法
        print("%s 的爱好是 %s" % (name, self.hobby))
def main():
    #ff = FatFather("胖子老板的父亲")
    fatboss = FatBoss("胖子老板", "打斗地主")
Nach dem Login kopieren

Im obigen Code verwende ich FatFather.init(self,name), um die Methode der übergeordneten Klasse direkt aufzurufen.

Die laufenden Ergebnisse sind wie folgt:

if __name__ == "__main__":
    main()
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主
Nach dem Login kopieren
Nach dem Login kopieren

2. Grundkonzepte der super()-Methode

Zusätzlich zur Methode der direkten Verwendung von FatFather .init(self,name) und kann auch mit der Methode super() aufgerufen werden.

Dann müssen Sie zunächst die Beschreibung und Syntax der super()-Methode lesen, um die Verwendung der super()-Methode zu verstehen.

2.1 Beschreibung

Die Funktion super() ist eine Methode zum Aufrufen der übergeordneten Klasse (Superklasse).

super wird verwendet, um das Problem der Mehrfachvererbung zu lösen. Der direkte Aufruf der Methode der übergeordneten Klasse unter Verwendung des Klassennamens ist bei Verwendung der Einzelvererbung kein Problem. Wenn Sie jedoch die Mehrfachvererbung verwenden, ist die Suchreihenfolge (MRO) erforderlich. und wiederholte Anrufe (Diamantvererbung) und andere Probleme.

MRO ist die Methoden-Parsing-Sequenztabelle der Klasse. Tatsächlich handelt es sich um die Sequenztabelle, wenn die Methode der übergeordneten Klasse geerbt wird.

Verwandte Empfehlungen: „Python-Video-Tutorial

2.2-Syntax

Das Folgende ist die Syntax von super() Methode:

super(type[, object-or-type])
Nach dem Login kopieren

Parameter

Typ – Klasse

Objekt-oder-Typ – Klasse, normalerweise selbst

Eine von Python3.x und Python2 .x Der Unterschied ist: Python 3 kann super().xxx direkt anstelle von super(Class, self).xxx verwenden:

Python3.x-Beispiel:

class A:
    pass
class B(A):
    def add(self, x):
        super().add(x)
Nach dem Login kopieren

Python2.x-Beispiel:

class A(object):   # Python2.x 记得继承 object
    pass
class B(A):
    def add(self, x):
        super(B, self).add(x)
Nach dem Login kopieren

2.3 Einzelvererbung verwendet super()

Verwenden Sie die super()-Methode, um den Init-Konstruktor neu zu schreiben, den der dicke Chef gerade von der übergeordneten Klasse geerbt hat

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')
# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        #FatFather.__init__(self,name)   # 直接调用父类的构造方法
        super().__init__(name)
        print("%s 的爱好是 %s" % (name, self.hobby))
def main():
    #ff = FatFather("胖子老板的父亲")
    fatboss = FatBoss("胖子老板", "打斗地主")
Nach dem Login kopieren

Verwenden Sie es von oben. Wenn Sie die Super-Methode verwenden, kann sie direkt verwendet werden, da es sich um eine Einzelvererbung handelt.

läuft wie folgt:

if __name__ == "__main__":
    main()
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主
Nach dem Login kopieren
Nach dem Login kopieren

Warum heißt es also, dass die Einzelvererbung direkt genutzt werden kann? Denn wenn die super()-Methode über Mehrfachvererbung verfügt, kommt es zu einem MRO-Aufrufreihenfolgeproblem (Sequenztabelle beim Erben der Methode der übergeordneten Klasse).

Sie können es unten ausdrucken, um die MRO-Sequenz der Einzelvererbung (FatBoss.mro) anzuzeigen.

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')
# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        #FatFather.__init__(self,name)   # 直接调用父类的构造方法
        super().__init__(name)
        print("%s 的爱好是 %s" % (name, self.hobby))
def main():
    print("打印FatBoss类的MRO")
    print(FatBoss.__mro__)
    print()
    print("=========== 下面按照 MRO 顺序执行super方法 =============")
    fatboss = FatBoss("胖子老板", "打斗地主")
Nach dem Login kopieren

Der obige Code verwendet FatBoss.mro, um die vom C3-Algorithmus des Python-Parsers berechnete Vererbungsaufrufsequenz der FatBoss-Klasse auszudrucken.

Führen Sie Folgendes aus:

if __name__ == "__main__":
    main()
打印FatBoss类的MRO
(<class &#39;__main__.FatBoss&#39;>, <class &#39;__main__.FatFather&#39;>, <class &#39;object&#39;>)
=========== 下面按照 MRO 顺序执行super方法 =============
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主
Nach dem Login kopieren

Aus den obigen Ergebnissen (, ,

Was sind also die Probleme bei Mehrfachvererbung?

2.4 Mehrfachvererbung mit super()

Angenommen, wir schreiben eine weitere Klasse für die Tochter des dicken Chefs und eine Klasse für die Frau des dicken Chefs Gleichzeitig muss die Tochter beide Kategorien gleichzeitig erben (Kategorie „fetter Chef“, Kategorie „fette Cheffrau“).

Weil der dicke Chef ein Hobby hat, muss die Frau des dicken Chefs arbeiten und Hausarbeit machen, also muss seine Tochter gleichzeitig helfen.

Zu diesem Zeitpunkt muss die Tochter die Methoden dieser beiden Elternklassen erben und verwenden. Wie schreibt man es also?

Werfen wir einen Blick auf den Implementierungscode:

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name, *args, **kwargs):
        print()
        print("=============== 开始调用 FatFather  ========================")
        print(&#39;FatFather的init开始被调用&#39;)
        self.name = name
        print(&#39;调用FatFather类的name是%s&#39; % self.name)
        print(&#39;FatFather的init调用结束&#39;)
        print()
        print("=============== 结束调用 FatFather  ========================")
# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby, *args, **kwargs):
        print()
        print("=============== 开始调用 FatBoss  ========================")
        print(&#39;胖子老板的类被调用啦!&#39;)
        #super().__init__(name)
        ## 因为多继承传递的参数不一致,所以使用不定参数
        super().__init__(name, *args, **kwargs)
        print("%s 的爱好是 %s" % (name, hobby))
        print()
        print("=============== 结束调用 FatBoss  ========================")
# 胖子老板的老婆类 继承 FatFather类
class FatBossWife(FatFather):
    def __init__(self, name, housework, *args, **kwargs):
        print()
        print("=============== 开始调用 FatBossWife  ========================")
        print(&#39;胖子老板的老婆类被调用啦!要学会干家务&#39;)
        #super().__init__(name)
        ## 因为多继承传递的参数不一致,所以使用不定参数
        super().__init__(name, *args, **kwargs)
        print("%s 需要干的家务是 %s" % (name, housework))
        print()
        print("=============== 结束调用 FatBossWife  ========================")
# 胖子老板的女儿类 继承 FatBoss FatBossWife类
class FatBossGril(FatBoss, FatBossWife):
    def __init__(self, name, hobby, housework):
        print(&#39;胖子老板的女儿类被调用啦!要学会干家务,还要会帮胖子老板斗地主&#39;)
        super().__init__(name, hobby, housework)
def main():
    print("打印FatBossGril类的MRO")
    print(FatBossGril.__mro__)
    print()
    print("=========== 下面按照 MRO 顺序执行super方法 =============")
    gril = FatBossGril("胖子老板", "打斗地主", "拖地")
Nach dem Login kopieren

Die laufenden Ergebnisse lauten wie folgt:

if __name__ == "__main__":
    main()
打印FatBossGril类的MRO
(<class &#39;__main__.FatBossGril&#39;>, <class &#39;__main__.FatBoss&#39;>, <class &#39;__main__.FatBossWife&#39;>, 
<class &#39;__main__.FatFather&#39;>, <class &#39;object&#39;>)
=========== 下面按照 MRO 顺序执行super方法 =============
胖子老板的女儿类被调用啦!要学会干家务,还要会帮胖子老板斗地主
=============== 开始调用 FatBoss  ========================
胖子老板的类被调用啦!
=============== 开始调用 FatBossWife  ========================
胖子老板的老婆类被调用啦!要学会干家务
=============== 开始调用 FatFather  ========================
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
=============== 结束调用 FatFather  ========================
胖子老板 需要干的家务是 拖地
=============== 结束调用 FatBossWife  ========================
胖子老板 的爱好是 打斗地主
=============== 结束调用 FatBoss  ========================
Nach dem Login kopieren

Von den oben genannten laufenden Ergebnissen gebe ich bewusst den Anfang und das Ende von an Der Aufruf zu jeder Klasse ist alles ausgedruckt und markiert, was sichtbar ist.

Der Startaufruf jeder Klasse beginnt gemäß der MRO-Sequenz und endet dann nacheinander.

Da außerdem verschiedene übergeordnete Klassen vererbt werden müssen, sind die Parameter nicht unbedingt sicher.

Daher sollten alle übergeordneten Klassen die variablen Parameter *args und **kwargs hinzufügen, andernfalls wird ein Fehler gemeldet, wenn die Parameter nicht übereinstimmen.

3. Hinweise

·Super().init hat grundsätzlich keinen Unterschied in der Verwendung im Vergleich zur Klasse name.init bei Einzelvererbung.

·Aber es gibt einen Unterschied bei der Mehrfachvererbung. Die Supermethode kann sicherstellen, dass jede Methode der übergeordneten Klasse nur einmal ausgeführt wird, während die Methode, die den Klassennamen verwendet, dazu führt, dass die Methode ausgeführt wird mehrmals ausgeführt werden. Sie können versuchen, einen Code zu schreiben, um die Ausgabe anzuzeigen.

·Verwenden Sie bei Verwendung der Mehrfachvererbung die Super-Methode, um Parameter an die übergeordnete Klasse zu übergeben. Dies sollte am Super-Algorithmus in Python liegen, andernfalls wird ein Fehler gemeldet wird gemeldet.

·Bei Verwendung der Super-Methode können bei Verwendung der Einzelvererbung nicht alle Parameter übergeben werden. Sie können nur die von der übergeordneten Klassenmethode benötigten Parameter übergeben, andernfalls wird ein Fehler gemeldet.

·Bei Verwendung der Mehrfachvererbung müssen Sie im Vergleich zur Verwendung der Methode „class name.init“ alle übergeordneten Klassen einmal schreiben, bei der Verwendung der Super-Methode müssen Sie jedoch nur eine schreiben Satz, um alles auszuführen Die Methode der übergeordneten Klasse. Dies ist auch einer der Gründe, warum bei der Mehrfachvererbung alle Parameter übergeben werden müssen.

4. Übung

Was wird die Ausgabe des folgenden Codes sein?

class Parent(object):
    x = 1
class Child1(Parent):
    pass
class Child2(Parent):
    pass
print(Parent.x, Child1.x, Child2.x)
1 1 1
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
1 2 1
Nach dem Login kopieren

Hinweis: Kind1 hat bereits sein eigenes x

Parent.x = 3
print(Parent.x, Child1.x, Child2.x)
3 2 3
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung der super()-Methode in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:jianshu.com
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
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage