Реализовать класс Python на основе параметра, переданного в конструктор

Я реализую класс Python, который создает другой объект в конструкторе, тип которого определяется на основе переданного ему параметра. Например, в приведенном ниже коде "workerA" имеет поведение класса "MyAClass", а "workerB" объект имеет поведение "MyBClass".

Я использую этот метод вместо получения другого класса из базового класса, потому что BaseClass уже используется в другом коде, который нельзя изменить. Поэтому, если я хочу другое поведение BaseClass, как для поведения "MyBClass", мне нужно только передать ему параметр dbtype = "MyBClass".

Есть ли лучший метод, который можно использовать и который дает тот же результат?

  import sys

  # MyAClass definition
  class MyAClass :

     def __init__(self, serverSettings):
        self._serverSettings = serverSettings

     def initialize(self):
        self._init = 1;
        print("Calling", sys._getframe(1).f_code.co_name)

     def add(self):
        self._init = 2;
        print("Calling", sys._getframe(1).f_code.co_name)

     def finalize(self):
        self._init = 3;
        print("Calling", sys._getframe(1).f_code.co_name)

     def __del__(self):
        print('Calling destructor of class ', self.__class__.__name__)


  # MyBClass definition
  class MyBClass :

     def __init__(self, serverSettings):
        self._serverSettings = serverSettings

     def initialize(self):
        self._init = 1;
        print("Calling", sys._getframe(1).f_code.co_name)

     def add(self):
        self._init = 2;
        print("Calling", sys._getframe(1).f_code.co_name)

     def finalize(self):
        self._init = 3;
        print("Calling", sys._getframe(1).f_code.co_name)

     def __del__(self):
        print('Calling destructor of class ', self.__class__.__name__)


  # The base class which will be called in main program
  class BaseClass :

     def __init__(self, serverSettings, dbtype = None):

        if(dbtype == None):
           self.__worker = MyAClass(serverSettings)
        elif(dbtype == "MyBClass") :
           self.__worker = MyBClass(serverSettings)
        else :
           print("Undefined type")

     def initialize(self):
        self.__worker.initialize()

     def add(self):
        self.__worker.add()

     def finalize(self):
        self.__worker.finalize()


  if __name__ == "__main__":

     serverSettings = dict()

     serverSettings["address"] = "localhost"
     serverSettings["name"] = "Testname"

     workerA = BaseClass(serverSettings)
     workerA.add()

     workerB = BaseClass(serverSettings, dbtype = "MyBClass")
     workerB.finalize()

person Gourish    schedule 20.04.2017    source источник
comment
Вместо использования аргумента dbtype вы можете просто использовать правильный класс.   -  person Klaus D.    schedule 20.04.2017
comment
@Kluas D, я попробовал метод передачи класса, и это сработало. Мне это показалось лучшим методом, чем то, что я реализовал. Спасибо   -  person Gourish    schedule 20.04.2017


Ответы (2)


Я знаю, что это не дает того же результата, что и ваша исходная программа, но подойдет ли что-то подобное для ваших целей? Если вы не запрашиваете имя метода (как указано выше), вы должны получить функционально идентичные результаты.

class BaseClass :
    def __init__(self, serverSettings, dbtype=None):

        if(dbtype == None):
           self.__worker = MyAClass(serverSettings)
        elif(dbtype == "MyBClass") :
           self.__worker = MyBClass(serverSettings)
        else :
           print("Undefined type")

    def __getattribute__(self, x):
        settings = object.__getattribute__(self, '__dict__').get('_BaseClass__worker')
        return settings.__getattribute__(x)

В качестве альтернативы, используя твизз класса, например:

class BaseClass :
    def __init__(self, serverSettings, dbtype='MyAClass'):
        dbtypes = {'MyAClass': MyAClass,
                    'MyBClass': MyBClass}
        if dbtype not in dbtypes:
           raise("Undefined type")
        self.__class__ = dbtypes[dbtype]
        self.__init__(serverSettings)
person lungj    schedule 20.04.2017

Я сделал следующие изменения кода на основе предложений

  class BaseClass :

     def __init__(self, serverSettings, Classtype = MyAClass):

        authclasses = [MyAClass, MyBClass]
        if Classtype not in authclasses :
           self.__worker = MyAClass(serverSettings)
        else :
           self.__worker = MyBClass(serverSettings)

     def __getattribute__(self, x):
        settings = object.__getattribute__(self, '__dict__').get('_BaseClass__worker')
        return settings.__getattribute__(x)
person Gourish    schedule 20.04.2017