Auto-generate methods for subclasses

348 Views Asked by At

I have a few dozen classes. Here are two of them:

class Class_A(ClassABC):

    def __init__(self):
        super().__init__()

    def from_B(self, b):
        #do stuff

    def from_C(self, c):
        #do stuff

    #...

    def to_B(self):
        rt = Class_B()
        rt.from_A(self)
        return rt

    def to_C(self):
        rt = Class_C()
        rt.from_A(self)
        return rt

    #...

class Class_B(ClassABC):

    def __init__(self):
        super().__init__()

    def from_A(self, a):
        #do stuff

    def from_C(self, c):
        #do stuff

    def to_A(self):
        rt = Class_A()
        rt.from_B(self)
        return rt

    def to_C(self):
        rt = Class_C()
        rt.from_B(self)
        return rt

    #...

 #class Class_C, Class_D, Class_E, etc,

and here is the ABC:

class ClassABC(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def __init__(self):
        #do stuff

The problem I have is that all the to_* methods in the subclasses follow the same exact pattern, and it becomes tedious to implement them. I would like to automatically generate them in the ClassABC if possible, but so far I have failed. I also tried creating a class decorater for the subclasses, but that didn't work either. I have, however, managed to auto generate the methods in each subclass using exec(), but I rather have the ABC generate them or use class decoraters. Is there a way to do this?

Note: all the classes are in their own separate module

1

There are 1 best solutions below

3
JAB On

First of all, your to_* methods aren't going to work because you need to explicitly include self at the beginning of the argument list to be able to use it in the method body. Secondly, I'd go with something akin to JBernardo's suggestion.

def to_class(self, cls):
    rt = cls()
    rt.from_class(self.__class__)
    return rt

def from_class(self, cls):
    #do stuff, with different things happening based on what class cls is; this may be a good place to use a dict of functions with the class or classname as keys