0

I would normally write a simple class like the one below. Initialize a python list in __init__ and collect results from different methods. This works as expected.

class my_class:
    def __init__(self, res = []):
        self.res = res
        
    def method_1(self):
        self.res.append('a')
        
    def method_2(self):
        self.res.append('b')
        
obj = my_class()
obj.method_1()
obj.res
obj.method_2()
obj.res

However, the number of methods grows very quickly and I was hoping to break it to smaller classes. I am not sure if this can be done with a class inheritance, see below. My goal here is to have a global self.res that records results from calls of various methods and can be accessed across smaller classes.

class my_class:
    def __init__(self, res = []):
        self.res = res

class my_class_1(my_calss):
    def __init__(self, res):
        super().__init__(res) 
        
    def method_1(self):
        self.res.append('a')

class my_class_2(my_class):    
    def __init__(self, res):
        super().__init__(res) 
    
    def method_2(self):
        self.res.append('b')

[Update]: The context for the question: I am building a webpage which contains different tabs; for each tab it contains figures and tables. Instead of using one class, which grows lines quickly, I decide to create separate classes for each tab. However, I want to maintain a dictionary that collects all the figures and tables across the classes, so that I can apply logic to update figure from the trigger from another table (table and figure could be at different tabs). I am not sure what is the best class structure.

Chenyang
  • 161
  • 1
  • 11
  • 2
    you should be careful using an empty list as a default argument https://stackoverflow.com/questions/26320899/why-is-the-empty-dictionary-a-dangerous-default-value-in-python – Nin17 Jun 02 '22 at 21:25
  • 2
    Is there a bigger reason you want subclasses, other than shortening the list of methods? – Guimoute Jun 02 '22 at 21:25
  • 1
    What exactly is your question about this? – mkrieger1 Jun 02 '22 at 21:32
  • I want to break down the original class structure into smaller ones, while maintaining a global variable that collects the results across classes. I am not sure what is the best way of doing this. – Chenyang Jun 02 '22 at 21:41
  • Use composition (and delegation, if necessary) rather than inheritance. "breaking something down into smaller parts" is exactly what that is for. Inheritance does not make sense: is a tab a kind of webpage? Composition does: does a webpage have tabs in it? "Instead of using one class, which grows lines quickly, I decide to create separate classes for each tab." Think about it carefully: does each tab actually *behave* differently? Or do they just have separate *data*? – Karl Knechtel Jun 02 '22 at 22:24

1 Answers1

0

Create classes dynamically with type and store them in a dictionary. Here a basic example:

...
# list of methods, assumed they exists in the base class
methods = ['method_1', 'method_2']

# dynamically create (sub)classes
constructor = lambda self, lst: super(type(self), self).__init__(lst)
new_classes = {}
for i, m_name in enumerate(methods, 1):
    d = {'__init__': constructor}
    new_classes[f'my_class_{i}'] = type(f'my_class_{i}', (my_class,), d)

# test:
print(issubclass(new_classes['my_class_2'], my_class))
# True

c2 = new_classes['my_class_2']([1, 2])
c2.method_2()
print(c2.res)
#[1, 2, 'b']

Remark: the declaration of the methods in the child classes is redundant... just omit them if are the same as in the base class

cards
  • 3,936
  • 1
  • 7
  • 25