Sarath R Nair
Sarath R Nair

Reputation: 495

Dynamically Change Base Class Python?

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?

Upvotes: 0

Views: 1306

Answers (2)

Mhadhbi issam
Mhadhbi issam

Reputation: 420





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__

Upvotes: 0

Will Da Silva
Will Da Silva

Reputation: 7040

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.

Upvotes: 1

Related Questions