2016-07-18 6 views
0

ich einen Python Vortrag auf Youtube beobachten und fand eine interessante Sprache-Funktion. Wenn ich jedoch versucht habe, einen Testcode auszuführen, hat es nicht funktioniert und ich würde gerne verstehen, warum.Call Resolution, um in Python mit Mehrfachvererbung

Ich hatte erwartet, das diese drucken:

Parent 
OtherParent 

Aber stattdessen habe ich dies:

Parent 
Parent 

Beispielcode:

class Parent: 
    def get_message(self): 
     return "Parent" 

class Child(Parent): 
    def do_print(self): 
     print(super().get_message()) 

class OtherParent: 
    def get_message(self): 
     return "OtherParent" 

class OtherChild(Child, OtherParent): 
    pass 

Child().do_print() 
OtherChild().do_print() 

Edit: Laufen auf Windows, Python 3.5 .1, Anaconda 4.0.0 (64-Bit)

+0

Was ist Ihre Python-Version? – Ohumeronen

+2

'print (OtherChild .__ MRO __)' sollte Ihre Frage – jonrsharpe

+1

+1 auf die '__mro__' Erklärung des Verhaltens beantworten. Siehe [hier] (http://Stackoverflow.com/a/10018792/426790) für eine Antwort über die Reihenfolge der Mixins, die sich auf OtherChild auswirken (kurze Antwort: "Das MRO ist im Wesentlichen die Tiefe zuerst, von links nach rechts"). –

Antwort

1

Die richtige Erklärung ist in den Kommentaren der Frage erwähnt, dh von HRG der OtherChild Klasse (Link im Kommentar gepostet: How does the order of mixins affect the derived class?).

Siehe die verschiedenen Ausgänge des HRG der OtherChild Klasse auf die verschiedenen Erbschaften abhängig:

  1. OtherParent keine Elternklasse haben:

    class OtherParent(): 
        def get_message(self): 
         return "OtherParent" 
    
    print(OtherChild.__mro__) 
    Child().do_print() 
    OtherChild().do_print() 
    

    Ausgabe zeigt, dass Parent vor OtherParent kommt:

    (<class '__main__.OtherChild'>, <class '__main__.Child'>, <class '__main__.Parent'>, <class '__main__.OtherParent'>, <class 'object'>) 
    Parent 
    Parent 
    
  2. Parent ist die Elternklasse von OtherParent:

    class OtherParent(Parent): 
        def get_message(self): 
         return "OtherParent" 
    

    Ausgabe zeigt, dass OtherParent jetzt vor Parent kommt: 2

    (<class '__main__.OtherChild'>, <class '__main__.Child'>, <class '__main__.OtherParent'>, <class '__main__.Parent'>, <class 'object'>) 
    Parent 
    OtherParent 
    
  3. Noch Fall aber jetzt OtherChild erbt zunächst von OtherParent, dann Child:

    class OtherParent(Parent): 
        def get_message(self): 
         return "OtherParent" 
    
    class OtherChild(OtherParent, Child): 
        pass 
    

    Ou tput zeigt, dass OtherParent kommt wieder vor Parent, aber vor Child auch:

    (<class '__main__.OtherChild'>, <class '__main__.OtherParent'>, <class '__main__.Child'>, <class '__main__.Parent'>, <class 'object'>) 
    Parent 
    Parent 
    

Vielleicht kann jemand den letzten Fall erklären, die auf dem ersten Blick nicht natürlich ist.

+0

Kein Elternteil hat 'do_print', es ist nur in der' Child' Klasse definiert, meinst du 'get_message'? Aber selbst dann folge ich nicht ganz der Erklärung. – NikoNyrh

+1

@NikoNyrh dann * warum hast du es akzeptiert?! * Vielleicht wäre es besser, diese Frage vollständig zu löschen (du musst diese Antwort nicht akzeptieren und ablehnen), lies die verknüpfte Frage zu MRO-Bestellung und frage erneut, ob du still bist unsicher. Wie es aussieht, ist das Ganze ein Autowrack. – jonrsharpe

+0

Leider war ich zu eifrig, eine plausibel aussehende Antwort zu akzeptieren, bevor ich es im Detail lese:/Ich kann die Frage nicht löschen, da sie bereits Antworten hat. Nächstes Mal werde ich mehr Forschung betreiben, bevor ich die Frage stelle. – NikoNyrh

-2

Ah zeigte mein Freund aus dem Beispiel auf Youtube zu einer kleinen Abweichung aus:

class Parent: 
    def get_message(self): 
     return "Parent" 

class Child(Parent): 
    def do_print(self): 
     print(super().get_message()) 

class OtherParent(Parent): # <----- Inheritance of Parent makes it work 
    def get_message(self): 
     return "OtherParent" 

class OtherChild(Child, OtherParent): 
    pass 

Child().do_print() 
OtherChild().do_print() 
+3

Dies erklärt nicht wirklich * warum * der erste Code nicht wie erwartet funktioniert, oder wie diese Änderung es behebt. – jonrsharpe

+0

Leider kenne ich die innere Funktionsweise von Python nicht, um die Antwort im Detail zu kennen. – NikoNyrh

+1

Oh, du bist der OP - dann könntest du das zu der Frage hinzufügen, anstatt es als Antwort zu posten: * "es funktioniert wie erwartet, wenn ich' OtherParent' von 'Eltern' erben lasse, aber ich verstehe nicht Warum "* – jonrsharpe