jeudi 10 septembre 2015

Python function body depends on the type of the argument class

I am new to python and object oriented programming and I stumbled into a problem which I believe can someone with more experience can answer easily.

I am writing a statistical package in Python and there are two abstract classes for static and dynamic models, where the dynamic model class overloads some methods of the static model class. Moreover I have an estimation class which has call methods of the model class based on the type of the model class.

This is the simplified version of my first try on the setup:

from abc import ABCMeta, abstractmethod

class StaticModel():
    __metaclass__ = ABCMeta
    @abstractmethod   
    def LogObs(self,y):
        pass

class DynamicModel(StaticModel):
    __metaclass__ = ABCMeta
    @abstractmethod   
    def LogObs(self,y,x):
        pass
    @abstractmethod   
    def LogTrans(self,x):
        pass    

class StaticModelExample(StaticModel):
    def LogObs(self,y):
        print 'StaticModel '+str(y)

class DynamicModelExample(DynamicModel): 
    def LogTrans(self,x):
        return x+1    

    def LogObs(self,y,x):
        print 'DynamicModel '+str(y)+' '+str(x)  

class EstimationMethod():
    def __init__(self,model,y):
        self.model=model
        self.y=y
        if(str(model.__class__.__base__).find('DynamicModel')!=-1):
            print 'It is a dynamic model'            
            self.x=0
        elif(str(self.model.__class__.__base__).find('StaticModel')!=-1):
            print 'It is a static model'

    def Estimate(self):
        if(str(self.model.__class__.__base__).find('StaticModel')!=-1):
            self.model.LogObs(self.y)
        elif(str(self.model.__class__.__base__).find('DynamicModel')!=-1):
            self.model.LogObs(self.y,self.x)
            self.x=self.model.LogTrans(self.x)
            print 'new x '+str(self.x)
        else:
            'model probably inherited from wrong class'




y=1        
modelStatic=StaticModelExample()
estimationStatic=EstimationMethod(modelStatic,y)
estimationStatic.Estimate()

modelDynamic=DynamicModelExample()
estimationDynamic=EstimationMethod(modelDynamic,y)
estimationDynamic.Estimate()

This sort of does the trick but I don't think this is the best way of doing it, because I always have to write if statement when ever I would like to do something in the estimation which is specific to the dynamic model.

Any suggestion for a better design pattern or a trick would simplify the code. I guess this should be standard.

Aucun commentaire:

Enregistrer un commentaire