Creating a class-based reusable application
Question: I am trying to create a re-usable application in python 2.6.

I am developing server-side scripts for listening GPS tracking devices. The
script are using sockets.

I have a base class that defines the basic methods for handling the data sent
by device.

    
    
    class MyDevice(object):
        def __init__(self, db)
            self.db = db  # This is the class that defines methods for connecting/using database
    
        def initialize_db(self):
            ...
    
        def handle_data(self):
            self.initialize_db()
            ...
            self.process_data()
    
        def process_data(self):
            ...
            self.categorize_data()
    
        def categorize_data(self):
            ...
            self.save_data()
    
        def save_data(self):
            ...
    

This base class serves for many devices since there are only some minor
differences between the devices. So I create a class for each _specific_
device type and make arrangements which are specific to that device.

    
    
    class MyDeviceType1(Mydevice):
        def __init__(self, db):
            super(MyDeviceType1, self).__init__(db)
    
        def categorize_data(self):
            super(MyDeviceType1, self).categorize_data(self)
            self.prepopulate_data()
            ...  # Do other operations specific to device
    
        def prepopulate_data(self):
            """this is specific to Type1 devices"""
            ...
    
    
    class MyDeviceType2(Mydevice):
        def __init__(self, db):
            super(MyDeviceType1, self).__init__(db)
    
        def categorize_data(self):
            super(MyDeviceType1, self).categorize_data(self)
            self.unpopulate_data()
            ...  # Do other operations specific to device
    
        def unpopulate_data(self):
            """this is specific to Type2 devices"""
            ...
    

And I have socket listeners that listens specific sockets, and call related
class (`MyDeviceType1` or `MyDeviceType2`) like:

    
    
    conn, address = socket.accept()
    ...
    thread.start_new_thread(MyDeviceType1(db_connector).handle_data, ())
    

That structure is all fine and useful to me. One device (_MyDevice_) may have
many subtypes (_MyDeviceType1_ , _MyDeviceType2_) which inherits the base
class.

And there are more than one type of base devices. So there is _OtherDevice_
with subtypes _OtherDeviceType1_ etc.

`MyDevice` and `OtherDevice` works quite differently, so they are the base
types and underlying code is quite different in all of them.

I also have some add-on functionalities. These functionalities are usable by
one or two subtypes of nearly all device base types.

So I want to prepare a single reusable (plug-able) class that can be inherited
by any subtype that needs those functionalities.

    
    
    class MyAddOn(object):
        def remove_unusable_data(self):
           ...
    
        def categorize_data(self):
            super ???
            self.remove_unusable_data()
    

And here is the part that I stuck. Since this is an independent module, it
should not be inherited from `MyDevice` or `OtherDevice` etc, but not all sub
device types are using these functionalities, I can not inherit `MyDevice`
from `MyAddOn` too.

Only logical method looks like, inheriting the subtype `MyDeviceSubType1` from
both `MyDevice` and `MyAddOn`

    
    
    class MyDeviceType1(Mydevice, MyAddOn):
        def __init__(self, db):
            super(MyDeviceType1, self).__init__(db)
    
        def categorize_data(self):
            >> super(MyDeviceType1, self).categorize_data(self) <<
            self.prepopulate_data()
            ...  # Do other operations specific to device
    
        def prepopulate_data(self):
            """this is specific to Type1 devices"""
    

`super(MyDeviceType1, self).categorize_data(self)` is the problem part.
`super` is triggering the `Mydevice.categorize_data` but not
`MyAddOn.categorize_data`

Is there any way to trigger `MyAddOn` methods using `super` call or in a such
fashion that I do not need to call that class method seperately? Both
`MyDevice.categorize_data` and `MyAddOn.categorize_data` should be called.


Answer: This is called cooperative multiple inheritance in python and works just fine.

What you refer to as an "Addon" class, is generally called a "Mixin".

Just call the `super` method in your Mixin class:

    
    
    class MyAddOn(object):
        def remove_unusable_data(self):
           ...
    
        def categorize_data(self):
            super(MyAddon,self).categorize_data()
            self.remove_unusable_data()
    

I'd like to note some things:

  * The method resolution order is left to right
  * You have to call super
  * You should be using **kwargs for cooperative inheritance

* * *

It seems counterintuitive to call `super` here, as the parent of `MyAddon`
does not have an attribute called `categorize_data`, and you would expect this
notation to fail.

This is where the `super` function comes into play.
[Some](https://rhettinger.wordpress.com/2011/05/26/super-considered-super/)
consider this behaviour to be the best thing about python.

Unlike in _C++_ or _Java_ the `super` function does not necessarily call the
class' parent class. In fact it is impossible to know in advance which
function will be called by `super` because it will be decided at run-time
based on the [method resoltion
order](https://www.python.org/download/releases/2.3/mro/).

`super` in python should really be called `next` because it will call the next
method in the inheritance tree.

For Mixins it is especially important to call super, even if you're inheriting
from `object`.

For further information I advise to watch Raymond Hettinger's excellent talk
on [Super considered Super](https://www.youtube.com/watch?v=EiOglTERPEo) from
pycon 2015.

* * *

It's an excellent pattern to use in python. Here is a pattern I encounter
often when programming structured applications obeying the [open-closed
principle](https://en.wikipedia.org/wiki/Open/closed_principle):

I have this library class which is used in production:

    
    
    class BaseClassA(object):
       def __init__(self, **kwargs):
           ... Do something that's important for many modules
       def ...   
    
    class BaseClassB(object):
       def __init__(self, **kwargs):
           ... Do something that's important for many modules
       def ...   
    

Now you get a feature request that in a particular case both `BaseClassA` and
`BaseClassB` should implement feature X.

According to open-close you shouldn't have to touch existing code to implement
the feature, and according to DRY you shouldnt repeat the code.

The solution is to create a `FeatureMixin` and create empty child classes
which inherit from the base class and the mixin:

    
    
    class FeatureMixin(object):
        def __init__(self,**kwargs):
            ...do something specific
            return super(FeatureMixin,self).__init__(**kwargs)
    class ExtendedA(FeatureMixin,BaseClassA):
       pass
    class ExtendedB(FeatureMixin,BaseClassB):
       pass
    

