pythonic way to customize classes
Question: I am trying to figure out a clean way to use inheritance for custom classes. I
have the following directory structure.

    
    
    inheritTest.py
    Level1
        __init__.py
        t_Generic.py
    Level2
        __init__.py
        t_Custom.py
    

**Goal:** I want all the classes of t_Generic accessible by importing t_Custom
module and allow needed customization in t_Custom.

There is nothing in two of the **init**.py files above.

t_Generic.py contains some generic classes like these:

    
    
    class A(object):
        def __init__(self):
            self.hello = "Hello! I am Mr.A from t_generic"
        def someOtherMethod(self):
            pass
    
    class B(object):
        def __init__(self):
            self.hello = "Hello! I am Mr.B from t_generic"
        def someOtherMethod(self):
            pass
    
    class C(object):
        def __init__(self):
            self.hello = "Hello! I am Mr.C from t_generic"
        def changeHello(self):
            pass
    

Experimental t_Custom.py is as below:

    
    
    import Level1.t_Generic
    
    #Override any Generic classes in this module.
    
    #Option 1: Let's get Generic A so it lives in this scope as A
    from Level1.t_Generic import A
    
    #Option 2: Let's create B and inherit from Generic, make future custom changes here
    class B(Level1.t_Generic.B):
        def __init__(self):
            super(B,self).__init__()
    
    
    #I really want to inherit from C and change it's behavior
    class C(Level1.t_Generic.C):
        def __init__(self):
            super(C,self).__init__()
        def changeHello(self):
            self.hello = "Hello! I am Mr.C modified in t_Custom"
    

**Question:** What's the pythonic way to do something like this? Should I just
import all the generic classes in Custom module as in option 1 or should I
create an inherited class in Custom as in Option 2 and modify the ones I want
to inherit from?

Example use case in inheritTest.py:

    
    
    import Level2.t_Custom
    
    a = Level2.t_Custom.A()
    b = Level2.t_Custom.B()
    c = Level2.t_Custom.C()
    
    print a.hello
    print b.hello
    print c.hello
    c.changeHello()
    print c.hello
    

output:

    
    
    Hello! I am Mr.A from t_generic
    Hello! I am Mr.B from t_generic
    Hello! I am Mr.C from t_generic
    Hello! I am Mr.C modified in t_Custom
    


Answer: _I haven't tested this, but I think it should do what you want. Consider it
whiteboard code_

First, you need to use relative imports in t_Custom.py then import the generic
classes

    
    
    from ..Level1 import t_Generic
    from t_Generic import A as GenericA
    from t_Generic import B as GenericB
    from t_Generic import C as GenericC
    

I rename the classes to avoid any clashes in your module's namespace.

Now, to get your desired output, in t_Custom.py (copying your original code)

    
    
    A = GenericA # Just re-export the generic A class
    
    class B(GenericB):
        def __init__(self):
            super(B,self).__init__()
    
    #I really want to inherit from C and change it's behavior
    class C(GenericC):
        def __init__(self):
            super(C,self).__init__()
        def changeHello(self):
            self.hello = "Hello! I am Mr.C modified in t_Custom"
    

and then, to try and avoid exporting t_Generic.A etc from your module

    
    
    __all__ = ["A","B","C"]
    

As Alex mentioned in his comment, it is generally considered a "Bad Thing"
(TM) to pointlessly override a method of a base class. Only do that if you
want to modify or add behavior. Then t_Custom.py becomes more like this:

    
    
    from ..Level1 import t_Generic
    from t_Generic import A as GenericA
    from t_Generic import B as GenericB
    from t_Generic import C as GenericC
    
    A = GenericA # Just re-export the generic A class
    B = GenericB # I'll subclass when I know what I want to do to it
    
    #I really want to inherit from C and change it's behavior
    class C(GenericC):
        def changeHello(self):
            self.hello = "Hello! I am Mr.C modified in t_Custom"
    
    __all__ = ["A","B","C"]
    

