Vererbungs- und Init-Methode in Python

85

Ich bin Anfänger von Python. Ich kann Vererbung nicht verstehen und __init__().

class Num:
    def __init__(self,num):
        self.n1 = num

class Num2(Num):
    def show(self):
        print self.n1

mynumber = Num2(8)
mynumber.show()

ERGEBNIS: 8

Das ist in Ordnung. Aber ich ersetze Num2durch

class Num2(Num):
    def __init__(self,num):
        self.n2 = num*2
    def show(self):
        print self.n1,self.n2

ERGEBNIS: Error. Num2 has no attribute "n1".

Wie kann in diesem Fall Num2zugegriffen werden n1?

Yugo Kamo
quelle

Antworten:

143

In der ersten Situation Num2wird die Klasse erweitert, Numund da Sie die __init__()in benannte spezielle Methode nicht neu definieren Num2, wird sie von geerbt Num.

Wenn eine Klasse eine __init__() Methode definiert , wird die Klasseninstanziierung automatisch __init__()für die neu erstellte Klasseninstanz aufgerufen.

In der zweiten Situation, da Sie neu definiert werden __init__()in Num2Sie die eine in der Superklasse explizit aufrufen müssen ( Num) , wenn Sie das Verhalten erweitern möchten.

class Num2(Num):
    def __init__(self,num):
        Num.__init__(self,num)
        self.n2 = num*2
Mario Duarte
quelle
22
Ihr Zitat reicht nicht aus, um zu erklären, warum eine __init__Methode, die in einer abgeleiteten Klasse nicht definiert ist , vererbt wird. Dies liegt daran, dass "wenn ein angefordertes Attribut in der Klasse nicht gefunden wird, die Suche in der Basisklasse fortgesetzt wird". (doc)
eyquem
5
Es tut mir leid ... so funktioniert Vererbung im Grunde ... wenn Sie eine Klasse erben, erhalten Sie das gesamte Paket, sodass alles in der Oberklasse in der Unterklasse vorhanden ist. Wenn Sie eine Methode neu definieren, wird sie überschrieben. Das steht in Ihrem Code.
Coya
4
@ Mario-Duarte irgendeinen Grund, warum dies besser wäre als super(Num2, self).__init__(num)?
Guival
1
Ich habe gerade von der in dieser Antwort vorgeschlagenen Lösung auf die Verwendung umgestellt super, und mein Programm wird jetzt einige Sekunden schneller geladen. Keine Ahnung warum.
Guimoute
supersoll bei der Verwendung von Mehrfachvererbung hilfreich sein. Bei Einzelvererbung liegen die Vorteile nicht auf der Hand.
Johann Bzh
4

Da Sie nicht aufrufen Num.__init__, wird das Feld "n1" nie erstellt. Rufen Sie es an und dann wird es da sein.

Danny Milosavljevic
quelle
1

Eine einfache Änderung in der Num2-Klasse wie folgt:

super().__init__(num) 
it works in python3

class Num:
        def __init__(self,num):
                self.n1 = num
class Num2(Num):
        def __init__(self,num):
                super().__init__(num)
                self.n2 = num*2
        def show(self):
                print (self.n1,self.n2)
mynumber = Num2(8)
mynumber.show()
Sacchit Jaiswal
quelle