CharcoalG
CharcoalG

Reputation: 315

Conditional python class inheritance

I have some class inheritance.

class A1:
    def __init__(self, b):
        self.b = b

    def some_A_function():
        print("This is A1 function")

    # ... more A1 specific functions

class B(A1):
    def __init__(self, a, b):
        super().__init__(b)
        self.a = a

    # ... more B specific functions

class C(B):
    def __init__(self, a, b)
        super().__init__(a, b)
    # ... more C specific functions

if __name__ == "__main__":
    # Main instance
    a = 1
    b = 2
    C_obj = C(a, b)

Now, there is some introduction of class A2 as follows:

class A2:
    def __init__(self, b):
        self.b = b

    def some_A_function():
        print("This is A2 function")

Now, based on the value of a which is passed while creating an instance of class C, inheritance of class B is expected to change. For example, if a=1, B inherits class A1 else it inherits class A2.

I don't wish to change any code to class A1, A2, C and the main block as it has a huge amount of code around it which is practically very difficult to restructure it in any way. However, I can implement the logic based on the value of a to decide upon the inheritance of B by changing somethings in B or by calling some independent function.

I am new to factory functions in general. Most of the examples which I found in my search are implemented on the topmost level of hierarchy which assess the conditional and return the relevant implementation of the class (Something like if a==1, return C1 else C2. However, in my case, I don't know how to say to class C (in main function) to ask class B to inherit one of the two implementation of A (i.e. A1, A2) based on the value passed as the variable a.

Upvotes: 0

Views: 131

Answers (1)

Hugo Aboud
Hugo Aboud

Reputation: 472

Not the cleanest solution I guess, but it can be achieved this way:

class A1:
    def __init__(self, b):
        self.b = b
    def some_A_function(self):
        print("This is A1 function", "b = " + str(self.b))

class A2:
    def __init__(self, b):
        self.b = b
    def some_A_function(self):
        print("This is A2 function", "b = " + str(self.b))

def get_class_B(base):
    class B(base):
        def __init__(self, a, b):
            super().__init__(b)
            self.a = a
    return B

def create_obj_C(a, b):
    if (a == 1): base = get_class_B(A1)
    elif (a == 2): base = get_class_B(A2)

    class C(base):
        def __init__(self, a, b):
            super().__init__(a, b)

    return C(a,b)

Then you'd have to create C through the auxiliary method create_obj_C.

create_obj_C(1, 2).some_A_function() # "This is A1 function, b = 2"
create_obj_C(2, 8).some_A_function() # "This is A2 function, b = 8"

Upvotes: 2

Related Questions