Search code examples
pythoninheritancemultiple-inheritance

How can inherit from different classes depending on a condition?


I have two classes, A and B. Both have a foo method. In some cases, i wan't my class C to inherit foo (and other methods) from A in other cases from B. In the code example, C will always have the foo method from A:

class A:
    def foo(self):
        print('A.foo()')


class B:
    def foo(self):
        print('B.foo()')


class C(A, B):
    pass


C().foo()

How can i choose which foo method to inherit? like:

class C(A,B):
    def __init__(self, inherit_from):
        if inherit_from == "A":
            # inherit methods from A
        elif inherit_from == "B":
            # inherit methods from B

Solution

  • You don't want to make C a subclass, but rather a superclass, and make the decision of which type of object to create at the time you initialize the object, rather than when you define the class:

    from abc import abstractmethod
    
    class C:
        @abstractmethod
        def foo(self) -> None:
             pass
    
    class A(C):
        def foo(self):
            print('A.foo()')
    
    class B(C):
        def foo(self):
            print('B.foo()')
    
    inherit_from = input("What type of C should I foo?")
    if inherit_from == 'A':
        c: C = A()
    elif inherit_from == 'B':
        c = B()
    else:
        raise ValueError(f"unknown C subclass {inherit_from}")
    
    c.foo()
    

    Note that this is really only important if you're using type checking (i.e. you want to be able to guarantee that c is going to be an object that implements a foo method -- the C superclass gives you a way to do that without specifying ahead of time whether it's an A or B). If you're not using type checking, then you can just skip defining class C entirely.