Python повторная реализация модели в экземпляре общего контроллера - PullRequest
1 голос
/ 25 марта 2020

Я пытаюсь создать gui, который включает в себя несколько кадров, которые должны иметь доступ и взаимодействовать с одним и тем же экземпляром модели. Поэтому я создаю экземпляр контроллера ctrl, который передается каждому кадру.

Вместо использования self.ctrl.model для каждого взаимодействия модели, я ввел self.model = self.ctrl.model во время инициализации кадра, чтобы повысить удобочитаемость. До сих пор это работало нормально для всех изменений в модели, то есть все изменения были распространены на контроллер и все остальные кадры. Однако одно приложение требует повторного создания модели. Поскольку переменные передаются посредством присваивания, повторное создание приводит к новому экземпляру Model(), который присваивается self.model в указанном кадре c, оставляя его отсоединенным от self.ctrl.model. Каков наилучший способ создания экземпляра модели так, чтобы все изменения распространялись на контроллер и другие кадры?

class Model():
    def __init__(self):
        self.par = "init"    

class Controller():
    def __init__(self):
        self.model = Model()

    def state(self):
        print("ctrl  | id:", id(self.model), "| par:", self.model.par)

class FrameA():
    def __init__(self, parent, ctrl):
        self.parent = parent
        self.ctrl = ctrl
        self.model = self.ctrl.model

    def modify(self):
        self.model.par = "modify"
        print("frame | id:", id(self.model), "| par:", self.model.par)

    def newmodel(self):
        self.model = Model()
        print("frame | id:", id(self.model), "| par:", self.model.par)

ctrl = Controller()
frameA = FrameA(None,ctrl)
ctrl.state()
frameA.modify()
ctrl.state() # changes in frameA propagate to ctrl
frameA.newmodel()
ctrl.state() # changes in frameA do not propagate to ctrl anymore

Вывод:

ctrl  | id: 2040845455712 | par: init
frame | id: 2040845455712 | par: modify
ctrl  | id: 2040845455712 | par: modify
frame | id: 2040845245128 | par: init
ctrl  | id: 2040845455712 | par: modify

Ответы [ 2 ]

1 голос
/ 25 марта 2020

Я мог бы подумать о 2 возможных решениях для получения желаемого поведения, однако могут быть и другие / более умные изменения:

  • не ленитесь и всегда обращайтесь к модели по self.ctrl.model
  • выполните повторное создание экземпляра, ссылаясь на контроллер self.ctrl.model = Model() и внедрите новый метод init_model() в каждом кадре, который снова устанавливает self.model = self.ctrl.model, так что сокращение self.model можно использовать как ранее
0 голосов
/ 25 марта 2020

Я думаю, что прекрасный способ достичь желаемого - использовать геттеры и сеттеры. Пример:

class Model:
  def __init__(self):
    pass

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

class Frame:
  def __init__(self, controller):
    self.controller = controller
    self.model = controller.model

  @property
  def model(self):
    return self.__model

  @model.setter
  def model(self, model):
    self.__model = model
    self.controller.model = model


controller = Controller(Model())
frame = Frame(controller)

print (id(frame.model), id(frame.controller.model))
frame.model = Model()
print (id(frame.model), id(frame.controller.model))
...