2016-10-07 3 views
3
class A: 
    def open_spider(self, spider): 
    #do some hacking 

class B(A): 
    def open_spider(self, spider): 
    super(B, self).open_spider(spider) 
    #something else 

Jetzt möchte ich C A Methode nennen, aber nicht B, die zumindest in zwei Arten erfolgen kann:Was ist der pythonische Weg, um die Elternmethode zu überspringen?

class C(B): 
    def open_spider(self, spider): 
     A.open_spider(self, spider) 
     #do things 

    class C(B): 
    def open_spider(self, spider): 
     super(B, self).open_spider(spider) 
     #do things 
+2

Es gibt keine Pythonic Weg, dies zu tun, denn es ist nicht etwas, was Sie tun sollten. Warum müssen Sie einen Teil des MRO überspringen? – jonrsharpe

+0

Ich wette, Sie haben einen guten Grund nicht zu, aber nur für den Fall ...Was ist, wenn C von A statt von B geerbt hat? Spart Ihnen viel Mühe. – Kevin

+0

Sie könnten Pythons verwenden name mangling 'A .__ open_spider' wird' c._A__open_spider' –

Antwort

1

Verwenden Sie die zweite Methode; Dies ist ein Grund, warum supereine Klasse als erstes Argument nimmt.

5

Sie können es mit der zweiten Möglichkeit tun. Aber ich muss sagen, dass der Teil, in dem das Kind die Elternmethode überspringt und den Großelternteil anruft, falsch ist und du solltest dein Design noch einmal anschauen und darüber nachdenken.

+1

Es ist normalerweise besser zu erklären, warum etwas nicht stimmt, sondern nur, dass es ist. Erklärungen helfen den Menschen, sie zu verstehen und zu befähigen, selbst logisch zu denken, anstatt sich von anderen bestätigen zu lassen. –

0

aktualisieren

Als Harry Percival states in seinem Buch Test-Driven Web Development with Python:

Persönliche Meinung hier: Ich super genutzt haben könnte, aber ich lieber nicht Verwendung super wenn es Argumente erfordert, zum Beispiel zu bekommen eine Großelternmethode. Ich finde Python 3 super() ohne Argumente großartig, um die sofortige Eltern zu bekommen. Alles andere ist zu fehleranfällig, und ich finde es außerdem hässlich.

Dort ist die Lösung, die er gibt, die Großelternklasse und ihre Methode direkt aufzurufen.

Etwas in den Zeilen:

class C(B): 
    def get_queryset(self): 
     return A.get_queryset(self) 

Welches ist Ihre erste Methode ist. Ich werde es definitiv annehmen. Vielen Dank!


Dies ist ein "einmaliger" Hack, um eine Methode einer Elternklasse vorübergehend zu überschreiben. Die Absicht ist, die Aufgabe zu erledigen, bis ein Refactoring stattfindet.

Sonst müssen Sie möglicherweise über das Design Ihrer Klassen wie Alex hingewiesen werden.

hatte ich die gleiche Frage, und schließlich kam ich auf die folgende Lösung:

class A: 
    def get_queryset(self): 
    # Do not hack around 

class B(A): 
    from_c = False 

    def get_queryset(self): 
    if self.from_c: 
     # Here goes the C hack 
    else: 
     # Here goes the B hack 

class C(B): 
    from_c = True 

I know that:

Es sollte one-- sein und vorzugsweise nur eine --obvious Weg TU es.

Ich habe das Gefühl, dass meine "Lösung" nur ein dritter Weg zu einem Hack ist. Jedoch:

  • Ich bin nicht Niederländisch.
  • Um das Ausmaß Ihres Beispiel ist dieser Trick komplex und praktisch, aber nicht kompliziert
+0

Wenn Sie Ihren Hack von C nach B bewegen, bin ich mir nicht sicher, ob das der richtige Weg ist. Was wäre, wenn Sie C1 - C5 - Klassen hätten? – VladimirLenin

+0

@VladimirLenin Ich habe meine Antwort aktualisiert und ein paar Links zur Verfügung gestellt, die Ihre erste Methode als Lösung fördern. – raratiru

Verwandte Themen