Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should python mix-in classes inherit only from object?

I have a mix-in class called WithAutoNumbering for classes that need a special numbering of a given attribute. Appart from that I have a nice class mix-in called WithIndexing for those classes that need indexing capabilities... which needs the capabilities of WithAutoNumbering.

Some classes need numbering but not indexing, so mixing them together is not a good idea.

The dilemma is, should WithIndexing inherit from WithAutoNumbering? or each class that needs WithIndexing should also inherit from WithAutoNumbering as well?

I.e. this, with CoolClass being the one that has to implement indexing:

class WithAutoNumbering(object):
    ...

class WithIndexing(WithAutoNumbering):
    ...

class CoolClass(WithIndexing):
    ...

or this

class WithAutoNumbering(object):
    ...

class WithIndexing(object):
    ...

class CoolClass(WithIndexing, WithAutoNumbering):
    ...

On the one hand, the first approach is more succint, and makes sure that you can't try to use WithIndexing withouth WithAutoNumbering. On the other hand, I have always read (and found it agreeable) that mix-ins should not have hierarchy, i.e. inherit only from object, in order to avoid spaghettization of the whole class hierarchy with ununderstandable __mro__s

like image 575
bgusach Avatar asked Nov 11 '22 04:11

bgusach


1 Answers

The issue with making a choice about what your mixins inherit from is that your choice will affect the final MRO of classes which use those mixins.

should WithIndexing inherit from WithAutoNumbering

As you say, WithIndexing uses WithAutoNumbering. It's a funny kind of class which cannot be used on its own at all; and by inheriting from WithAutoNumbering, WithIndexing can override WithAutoNumbering members.

In general, it will be easier for each level to override methods found above, the more you set this up as single inheritance.

However, if you choose to design the other way (such that you need to inherit from both to make a class capable of using WithIndexing), you will likely be completely fine, until something overrides a method found in WithAutoNumbering. In that case, the order in which the classes appear in the base list may affect their order of the MRO, in which case you may have surprising results. If you need the power to affect the MRO in that way, you should have each of these mixins inherit from object. You probably don't need that, though.

like image 56
Marcin Avatar answered Nov 14 '22 21:11

Marcin