2017-05-26 6 views
2

betrachten den folgenden Code:Vererbung: Werden bei jedem Aufruf von 'super' Elternobjekte erstellt?

class A: 
    def __init__(self): 
     print('class A is being constructed') 

    def print_msg(self): 
     print('Hello, I am class A') 

class B(A): 
    def __init__(self): 
     super(B, self).__init__() 
     print('class B is being constructed') 

    def print_msg(self): 
     super(B, self).print_msg() 
     print('Hello, I am class B') 

Wie Sie sehen können, ich nenne super(B, self) jedes Mal B.print_msg() genannt wird.

Meine Frage ist, ob jedes Mal, wenn ich es tue, es ein neues Objekt von A konstruiert, oder ist es ein Objekt, das anfänglich erstellt wurde, und ich jedes Mal seine Referenz bekomme?

Mit anderen Worten, würde der folgende Code A 100 mal konstruieren?

b = B() 
for i in range(100): 
    b.print_msg() 

Der Grund, warum ich in darüber Gedanken zu machen habe, ist, dass die .__init__() Methode der Eltern nicht automatisch aufgerufen wird, wenn das Objekt des Kindes angelegt wird.

+1

Was wird gedruckt, wenn Sie den Code ausführen? –

+0

@JimWright Es druckt die Nachricht von A, gefolgt von B's Nachricht einhundert Mal – Chur7U

+1

Nein, wenn Sie 'super()' verwenden, beziehen Sie sich nur auf ein vorhandenes ** Klasse ** -Objekt. – martineau

Antwort

2

super ist keine Funktion; es ist tatsächlich eine Klasse, deren Instanzen Wissen über die Methodenauflösungsreihenfolge der beteiligten Klassen einkapseln.

super(B, self) gibt eine Instanz (ein Proxy-Objekt), der die MRO für unabhängig von der Art kennt self hat, sowie die Tatsache, dass Sie die Klassen in der MRO zwischen self.__class__ und B überspringen wollen. Wenn Sie eine Methode auf dem Proxy aufrufen, findet sie die richtige Methode zum Aufrufen und übergibt dann self als Argument an diese Methode. Das Objekt self war eine Instanz einer Klasse A, deren MRO wie [A, C1, C2, C3, C4, B, C5, C6] aussah. Normalerweise würde ein Anruf an A.foo() überprüfen, ob A eine Methode foo hatte, und wenn nicht, fahren Sie fort, C1, C2 usw. zu überprüfen, bis es eine Klasse mit einer Methode foo fand. super(B, self) gibt einen Proxy zurück, der im Grunde sagt, "verwenden Sie eine MRO von [B, C5, C6]", so dass Python, wenn Sie super(B, self).foo() schreiben, direkt zu B springt, wenn A.foo nicht existiert.

In den meisten Fällen wird super verwendet, um die Klasse der Instanz selbst zu überspringen und eine Klasse vor der MRO zu trimmen. Dies ist das Verhalten, das Python 3 einfach macht, indem Sie die Argumente super weglassen.

1

Nein, der folgende Code wird ein A-Konstrukt genau einmal:

b = B() 
for i in range(100): 
    b.print_msg() 

Diese implizit in der Linie b = B() passieren würde, weil B ein A. ist

Das Objekt super(B, self) ist ein Proxy . Es wird das Klassenobjekt A verwenden, es muss jedoch keine Instanz von A erstellt werden.

Verwandte Themen