我试图构建一个涉及多个框架的gui,这些框架都应该访问同一个Model实例并与之交互。因此,我创建了一个控制器实例ctrl
,它被传递给每一帧。
我没有在每次模型交互中使用self.ctrl.model
,而是在帧初始化期间引入了self.model = self.ctrl.model
,以提高可读性。到目前为止,对于模型中的所有更改,这都运行良好,即所有更改都传播到控制器和所有其他帧。但是,一个应用程序需要重新实例化模型。当变量通过赋值传递时,重新实例化会导致一个新的Model()
实例,该实例在特定帧中被分配给self.model
,使其与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
我可以想出两种可能的解决方案来获得所需的行为,但可能还有其他/更聪明的变化:
- 不要懒惰,总是通过
self.ctrl.model
参考模型 - 参考控制器
self.ctrl.model = Model()
进行重新实例化,并在每帧中引入新的init_model()
方法,重新设置self.model = self.ctrl.model
,这样缩写self.model
就可以像以前一样使用
我认为使用getter和setter是实现您想要的目标的一种很好的方法。示例:
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))