Is it ok to use MRO to override mixin?

Problem Description: I have a class C inheriting from mixins A and B I want a new C_ class that has all the methods / attributes defined in class C , but with B replaced with B_ (the same API) in the inheritance scheme (one possible use of this is to simply mock it). All classes are new style classes.

I got what I wanted, messing around with the inheritance order, so MRO:

 AB B_ B_ AB \ / / \ \ / 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) 

The C2 method (inheriting the modified mixin before the C class) works without much surprise, and if I call the method defined in mixin B , the definition of B_ is selected.

At the moment it works, but I feel: "fingers crossed, I hope that a special case does not arise and does not break the system!"

Question : is, finally, not quite the right way to solve the problem, or is there a better way to do this?

PS: I think I can take my bazooka and create a metaclass to redefine mro ( as stated in the official document ), but my instinct says that this does not happen to be prettier.

+7
python multiple-inheritance mixins
source share
2 answers

Your approach should work fine. It is acceptable to use a subclass to control the MRO and obscure one class with another.

This blog post provides some examples: https://rhettinger.wordpress.com/2011/05/26/super-considered-super/

+2
source share

You already know it's dirty. If A and B (and therefore B ') were to have common attributes, then C would receive these attributes from A, and C_ would receive them from B_.

Assuming you are not using super () in any new methods defined in C, I would make C a simple class (no reason), and then write

 class D(C, A, B): pass class D_(C, A, B_): pass 
0
source share

All Articles