Python: Initialising a new derived class in a method of a base class

Viewed 464

My situation is that I have access to two classes that work nicely together. Modifying their code extensively is probably not possible but maybe small changes could be implemented. However, there are some small extensions to both classes that I would like to make. This seems like a job for subclassing, deriving from each class and adding functionality. But I've run into a problem because one base class calls the other, not my derived one.

Let's say I have two classes A and B in a module 'base_classes.py'. Class B has a method that creates an instance of class A and uses it e.g.

'base_classes.py'

class A():
    def __init__(self):
        print('Class A being called')

class B():
    def __init__(self):
        self.do_thing()
    def do_thing(self):
        self.myA = A() # Here class A is explicitly named

So I would like to subclass these two and extend them. I do that in a separate module:

'extensions.py'

import base_classes

class DerivedA(base_classes.A):
    def __init__(self):
        super().__init__()
        print('Class DerivedA being called')

class DerivedB(base_classes.B):
    pass

db = DerivedB()

As expected the output is simply

Class A being called  

But how can I prevent my subclass of B from making the instance of the base class of A in the method do_thing(self) and instead make an instance of DerivedA?

The simple way would be to override do_thing(self) in DerivedB so that it explicitly calls DerivedA e.g.

class DerivedB(base_classes.B):
    def do_thing(self):
        self.myA = DerivedA() # Here class DerivedA is explicitly named

This is fine for this small example, but what if do_thing(self) was a hundred lines long and contained many objects of type A? What if most methods in B contained some A objects. You'd have to override basically every method with an almost exact replica, making it pointless to derive from B in the first place. That's pretty much the problem in my case and I think there must be a clever pythonic way to solve this. Ideally without completely rewriting the original classes.

Any ideas?

1 Answers
Related