0

Assume I have 4 classes class ModelA, class ModelB, class ModelC class ModelD.

I have another class LongModel. I want to choose from the above 4 classes as the BaseClass for the class LongModel, based on model_name. What's the right way to do it. As of now, I am doing the following:

def get_long_model(model_name):
   if model_name == 'A':
       base_class = Model_A
   if model_name == 'B':
       base_class = Model_B
   if model_name == 'C':
       base_class = Model_C
   if model_name == 'D':
       base_class = Model_D
   
   return LongModel(base_class)

I really don't want to use a function. Can we do this over the LongModel itself?

For eg:

class LongModel():
    def __init__(self, model_name):
        if model_name == 'A':
             # Assign base class for LongModel

or some neat way using class or anything.

If I use composition then,

class LongModel():
    def __init__(self, model):
        self.model = model

long_model = LongModel(ModelA)

Then, assume ModelA has some attributes, which I want to use inside LongModel say the name, I have to add self.name = model.name, for one or 2 attributes its okay. But for all/most attributes isn't it difficult?

6
  • 6
    I would argue this is a good time for composition over inheritence meaning instead of swapping out the base class (inheritance) instead you should swap out a member variable of your class Commented Jun 14, 2021 at 13:52
  • Can you give me a basic layout example. Commented Jun 14, 2021 at 13:56
  • Obviously inheritance is done in class LongModel(BaseClass):, so no, you can't do what you want. Use composition. Commented Jun 14, 2021 at 13:56
  • There’s only one LongModel class object. You can’t dynamically switch out its base, since that changes it for every instance of LongModel. That’s simply not how that relationship works. Commented Jun 14, 2021 at 13:57
  • 1
    @SarathRNair the shared attributes can be defined in the outer class, while the specific attributes which are not shared by all can be defined in the inner class. If there are attributes which are only shared with some of the classes, consider using an intermediate class for those using either inheritance or composition as appropriate. Commented Jun 14, 2021 at 14:05

2 Answers 2

1

What you've described (using a function to select the class) is akin to using a factory, but has the disadvantage of remaking the classes each time it is run. This would mess with type checking/comparison. In general you should only create each class object exactly once.

If you'd like to control this behaviour from inside the LongModel class, you can do so by overriding its __new__ method as described here: https://stackoverflow.com/a/10357472/5946921

I do not recommend you do this, however, as it is most likely bad design. You should definitely generate all of your classes upfront, and then re-use those class objects, to prevent issues around type checking/comparison later on. Additionally, consider using composition instead of inheritance for this.

Sign up to request clarification or add additional context in comments.

3 Comments

The reason I thought this way is because if I define class LongModelA, class LongModelB so on, isn't it redundant in nature.? In the future, if I have more models like Model N, I have to keep re-writing them.
You can generate your classes dynamically using type, among other methods. The important thing is that you do it exactly once for each logical type. See: stackoverflow.com/questions/15247075
I went with composition
0




class base : 
    def print(self,x,y) : 
        return x + y 

class drived : 
    def print(self,x,y) : 
        return x + y + 1 


class test(base) : 
    pass 

# this simulate drived(base)
v = type('newdrived' , (drived,base), dict())
i = v()
r = i.print(1,1)
print(r)
assert test.__dict__ == v.__dict__

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.