Wie funktioniert eine Super-Methode in Python bei Mehrfachvererbung?

8

Wie funktioniert eine Super-Methode in Python?

Im angegebenen Code:

%Vor%

Wenn test auf D aufgerufen wird, gibt es B->C statt B->A aus (was ich erwartet habe).

Wie verhält sich Super innerhalb B zu einer Instanz von C?

    
Kuldeep K. Rishi 05.04.2014, 10:09
quelle

2 Antworten

1

Im allgemeinen Fall nimmt super () zwei Argumente an: eine Klasse und eine Instanz dieser Klasse. (1) Das Instanzobjekt (self) bestimmt, welche MRO zum Auflösen irgendwelcher Attribute verwendet wird. (2) Die bereitgestellte Klasse bestimmt eine Teilmenge dieses MRO, weil super () nur diejenigen Einträge in der MRO verwendet, die nach der bereitgestellten Klasse auftreten.

Im obigen Fall, wenn Super innerhalb von B von der Instanz von D Object aufgerufen wird, verweist das Selbst auf D Objekt (dh Instanzobjekt) und mro von D (dh Instanzobjekt) ist daher [D, B, C, A] entsprechend zu (2) werden nur diejenigen Einträge in MRO verwendet, die nach B auftreten. dh [C, A]

Daher wird empfohlen, die Klasse anzugeben, in der super () als erstes Argument und das Standard-self als zweites Argument verwendet wurde. Das resultierende Objekt behält das Instanz-Namespace-Dictionary von self bei, ruft jedoch nur Attribute ab, die für die später im MRO gefundenen Klassen definiert wurden, als die angegebene Klasse.

Wenn wir also B als

definieren %Vor%

ruft dann D () auf. test () gibt aus == & gt; "B- & gt; A" Erläuterung: von (1) über MRO von selbst == [D, B, C, A, Objekt] Von (2) oben werden nur jene Einträge von MRO verwendet, die nach der bereitgestellten Klasse (dh C) auftreten. daher wird super die Testmethode von A aufrufen.

    
Kuldeep K. Rishi 05.04.2014, 11:08
quelle
2

Aus der Dokumentation:

  

super (Typ [, Objekt oder Typ]):   Gibt ein Proxy-Objekt zurück, das Methodenaufrufe an eine übergeordnete oder gleichgeordnete Klasse des Typs

delegiert

Betonung meiner.

Der MRO (wie Sie ihn ausgedruckt haben) bestimmt die Reihenfolge der Methodenauflösung, in diesem Fall (D, B, C, A, Objekt). Also, super(B, self) , wenn innerhalb von D aufgerufen, gibt ein Proxy-Objekt zurück, das Methoden an seine Geschwister C delegiert, basierend auf dem MRO.

Dies kann tatsächlich verwendet werden, um das Verhalten in Vererbungshierarchien zu erweitern, ohne vorhandene Klassen zu ändern. Beachten Sie, dass B nicht wirklich weiß , zu welcher Klasse die Methode test() gesendet wird - sie verwendet einfach einen indirekten Aufruf super() . Sie können eine andere Klasse in das MRO einfügen, indem Sie einfach eine neue Klasse erstellen, die mehrere Basisklassen in der erforderlichen Reihenfolge mischt.

Angenommen, Ihre ursprüngliche Hierarchie enthielt nur die Klassen A , B und D . Angenommen, Sie mussten zu einem späteren Zeitpunkt alle Methodenaufrufe von B mit Protokollierung instrumentieren. Anstatt B zu ändern, könnten Sie einfach eine neue Klasse C erstellen, die die Protokollierung durchführt und D inherit C hat, wodurch sie direkt nach B in die MRO eingefügt wird.

    
spinlok 05.04.2014 10:47
quelle