I'd like to use a Mixin to always add some init functionality to my child classes which each inherit from different API base classes. Specifically, I'd like to make multiple different child classes that inherit from one of these different API-supplied base classes and the one Mixin, which will always have the Mixin initialization code executed in the same way, without code replication. However, it seems that the __init__ function of the Mixin class never gets called unless I explicitly call it in the Child class's __init__ function, which is less than ideal. I've built up a simple test case:
class APIBaseClassOne(object): def __init__(self, *args, **kwargs): print (" base ") class SomeMixin(object): def __init__(self, *args, **kwargs): print (" mixin before ") super(SomeMixin, self).__init__(*args, **kwargs) print (" mixin after ") class MyClass(APIBaseClassOne): pass class MixedClass(MyClass, SomeMixin): pass
As you can see in the following output, the Mixin function's init never gets called:
>>> import test >>> test.MixedClass() base <test.MixedClass object at 0x1004cc850>
Is there a way to do this (have an init function in a Mixin get called) without writing every child class to explicitly invoke the Mixin's init function? (i.e., without having to do something like this in every class:)
class MixedClass(MyClass, SomeMixin): def __init__(*args, **kwargs): SomeMixin.__init__(self, *args, **kwargs) MyClass.__init__(self, *args, **kwargs)
Btw, if all my child classes were inheriting from same base class, I realize I could create a new middle class that inherits from the base class and the mixin and keep it DRY that way. However, they inherit from different base classes with common functionality. (Django Field classes, to be precise).
Mixins are a language concept that allows a programmer to inject some code into a class. Mixin programming is a style of software development, in which units of functionality are created in a class and then mixed in with other classes. A mixin class acts as the parent class, containing the desired functionality.
A mixin is a class that provides method implementations for reuse by multiple related child classes. However, the inheritance is not implying an is-a relationship. A mixin doesn't define a new type. Therefore, it is not intended for direction instantiation.
Mixins are sometimes described as being "included" rather than "inherited". In short, the key difference from an inheritance is that mix-ins does NOT need to have a "is-a" relationship like in inheritance. From the implementation point of view, you can think it as an interface with implementations.
Mixins are an alternative class design pattern that avoids both single-inheritance class fragmentation and multiple-inheritance diamond dependencies. A mixin is a class that defines and implements a single, well-defined feature. Subclasses that inherit from the mixin inherit this feature—and nothing else.
Sorry I saw this so late, but
class MixedClass2(SomeMixin, MyClass): pass >>> m = MixedClass2() mixin before base mixin after
The pattern @Ignacio is talking about is called cooperative multiple inheritance, and it's great. But if a base class isn't interested in cooperating, make it the second base, and your mixin the first. The mixin's __init__()
(and anything else it defines) will be checked before the base class, following Python's MRO.
This should solve the general question, though I'm not sure it handles your specific use. Base classes with custom metaclasses (like Django models) or with strange decorators (like @martineau's answer ;) can do crazy things.
Have the base class invoke super().__init__()
even though it is a subclass of object
. That way all the __init__()
methods will be run.
class BaseClassOne(object): def __init__(self, *args, **kwargs): super(BaseClassOne, self).__init__(*args, **kwargs) print (" base ")
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