2015-02-01 4 views
7

Problembeschreibung: Ich habe eine Klasse C erben von Mixins A und B. Ich möchte eine neue Klasse, C_, mit allen Methoden/Attribute in der Klasse C aber mit B vertauscht mit B_ (gleiche API) im Vererbungsschema (eine mögliche Verwendung davon ist leicht verspotten). Alle Klassen sind neue Stilklassen.Ist es OK, den MRO zu benutzen, um einen Mixin zu überschreiben?

Ich habe, was ich wollte mit dem Erbe Ordnung durch Unordnung, damit die MRO:

A B B_ B_ A B 
\//  \ \/
    C /  \ C 
    \/   \/
    C1   C2 
C1(C,B_)  C2(B_,C) 

C1.__mro__ = (C1, C , A, B, B_, object) 
C2.__mro__ = (C2, B_, C, A, B , object) 

Die C2 Methode (das modifizierte mixin vor der C Klasse erben) ohne große Überraschung funktioniert und wenn ich einen Anruf Methode definiert in der B Mixin, die B_ Definition wird gewählt.

Für den Moment funktioniert es, aber ich fühle mich: "Daumen drücken, ich hoffe, dass ein spezieller Fall nicht auftaucht und das System bricht!"

Die Frage ist: ist es eine nicht-so-falsche Möglichkeit, das Problem zu lösen, oder gibt es einen besseren Weg, es zu tun?

PS: Ich denke, ich könnte meine Bazooka nehmen und eine Metaklasse erstellen, um die Mro (as said in the official doc) neu zu definieren, aber mein Instinkt sagt, dass es nicht unbedingt hübscher sein wird.

+1

ich etwas falsch nicht mit ihm sehen. Der zum Erstellen des MRO verwendete Algorithmus ist dokumentiert, und Sie können sich auf die Reihenfolge verlassen, die Sie sehen. – Bakuriu

+0

Hinweis: Wenn B_ von B erbt, wird es B im MRO vorangehen, unabhängig von der Reihenfolge in der Klassendefinition. Dies ist nicht Ihr Anwendungsfall, aber es könnte der Fall sein, wenn jemand nach diesem Thema sucht, also dachte ich, dass es vielleicht erwähnenswert wäre. Ich kann verstehen, warum B_ nicht von B erbt, aber beachte, dass du B nicht genau durch B_ ersetzt: Methoden, die in B und nicht in B_ definiert sind, werden immer noch von B übernommen. –

Antwort

0

Sie wissen bereits, das ist chaotisch. Wenn A und B (und damit B ') Attribute gemeinsam hätten, würde C diese Attribute von A bekommen, während C_ sie von B_ bekommen würde.

Angenommen, Sie verwenden Super nicht() in allen neuen Methoden in C definiert, würde ich C eine einfache Klasse machen (keine Basen) und dann schreiben

class D(C, A, B): pass 
class D_(C, A, B_): pass 
Verwandte Themen