Problem description: I have a class C
inheriting from mixins A
and B
.
I want a new class, C_
, having all the methods/attributes defined in the class C
but with B
swapped with B_
(same API) in the inheritance scheme (one possible use of this is easy mocking). All classes are new style classes.
I got what I wanted by messing with the inheritance order, therefore the 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)
The C2
method (inheriting the modified mixin before the C
class) works without much surprise and if I call a method defined in the B
mixin, the B_
's definition is chosen.
For the moment it works, but I feel like: "fingers crossed, I hope a special case does not arise and break the system !"
The question is: is it a finally-not-so-wrong way to solve the problem or is there a better way to do it ?
PS: I think I could take my bazooka and create a metaclass to redefine the mro (as said in the official doc), but my instinct says it's not going to be necessarily prettier.
Your approach should work just fine. It is legitimate to use a subclass to control the MRO and to shadow one class with another.
This blog post gives several examples: https://rhettinger.wordpress.com/2011/05/26/super-considered-super/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With