0

Right now, my project has the following structure :

main.py
-------

class main_fun(object):
    def __init__(self, <parameters>):


ops.py
------

class ops_fun(main_fun):
    def __init__(self):
        super(ops_fun, self).__init__(<parameters>)

It essentially translates to the following :

                              ------------------
                              main_fun (main.py)
                              ------------------
                                      |
                                      |
                               ----------------
                               ops_fun (ops.py)
                               ----------------

I would like to split/restructure the above into the following :

                              ------------------
                              main_fun (main.py)
                              ------------------
                            /         |          \
                           /          |           \
        ----------------     ----------------      ----------------
        AuxOps (aops.py) === CoreOps (cops.py) === DerOps (dops.py)
        ----------------     ----------------      ----------------
                           \          |           /
                            \         |          /
                              ------------------
                              con_fun (contf.py)
                              ------------------

Which basically means that I want to :

  1. inherit all methods/functions and variables from the class main_fun to each of AuxOps, CoreOps, DerOps and con_fun.
  2. have different methods/functions implemented in each of AuxOps, CoreOps and DerOps, should be inherited in each others' classes. i.e., AuxOps should inherit every method in CoreOps and DerOps, DerOps should inherit every method in CoreOps and AuxOps.
  3. inherit each of AuxOps, CoreOps and DerOps in con_fun (Does inheriting these automatically inherit main_fun, since it is the parent of these?).

How can I achieve the above?

1
  • 1
    I'm quite new to multi-inheritance, but can you try this : ```` class con_fun(AuxOps,CoreOps,DerOps): pass ```` Commented Mar 28, 2019 at 10:49

2 Answers 2

3

Python allows multiple inheritance, so you can directly

class Parent ...

class ChildA(Parent) ...
class ChildB(Parent)...

class Grandchild(ChildA, ChildB)...

The child inherits all of its parents methods. This causes the problem that the Grandchild will inherit the methods of the Parent class through both of the parents. By default, when asked to call the method, python will look at the leftmost parent class first.

For more details, look up diamond problem and python's method resolution order.

Sign up to request clarification or add additional context in comments.

2 Comments

So, for class ChildA, can I do class ChildA(Parent, ChildB, ChildC) so that all the methods of ChildB and ChildC are inherited to it. And likewise for ChildB and ChildC? If yes, is it a good practice?
Almost. If ChildA inherits from ChildB, then ChildB can't inherit from ChildA. You have to inherit from the class(es) that are higher in your diagram, you can't inherit from those that are on the same level.
2

An opinionated answer. I'd recommend composing using a base class and plug-ins. Multiple inheritance of general classes can be an utter pain to debug.

class AuxPlugin( object):
    def auxMethod1( self, ...)

    ...

class CorePlugin( object)
    def coreMethod1( self, ...)
    ...

class DerPlugin( object)
    def derMethod1( self, ...)
    ...

class AuxOps( AuxPlugin, Main_Fun):  # better, call Main_Fun Base_whatever
    pass
class CoreOps( CorePlugin, Main_Fun):  
    pass
class DerOps( DerPlugin, Main_Fun): 
    pass
class ConFun( AuxPlugin, CorePlugin, DerPlugin, Main_Fun ):
    pass
# and possible
# class CoreDerOps( CorePlugin, DerPlugin, Main_Fun):
#    pass
# etc. Mix'n'match.

The "rules" are:

  1. Plugins always inherit from object, and do not do anything except define ordinary methods.
  2. Plugins all go to the left of the single base class in classes inheriting the base class
  3. Plugins should have their own unique set of methods that do not overlap with other compatible plugins (but if they do, the leftmost plugin wins)
  4. If you break these rules you will regret it later when you forget you did, or some other poor sod will curse you and damage your karma.

You can repeat this pattern multiple levels deep:

class FooFun( FooPlugin, ConFun):  
   # gets all of ConFun's plug-in methods, its base class, and added FooPlugin's methods

One level down, it is permissible to have plugged-in methods that intercept and augment methods inherited from a lower level, calling super().name() where appropriate.

The key thing is that finding out what refers to what is easy. If it's in a Plugin, there is no superclass to worry about. Any calls to super() refer to the base class, or further up its inheritance tree.

4 Comments

So, "plugins" is an informal name given for this inheritance tool?
Yes. Its a way of programming in Python, not anything built into the language. A "plugin" class is useless on its own, useful only when "plugged in" (inherited) along with a base class.
Great. Also, if I have a variable say self.A declared and updated in grandchild class, would it be available in a method in the child class as well as parent class? (I haven't tried this in even a regular hierarchy!)
Yes, Python doesn't hide anything or have private variables. self refers to the instance and all the class / subclass code shares that instance.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.