在MVC中实例化视图,模型和数据库

时间:2015-02-18 04:52:54

标签: python python-3.x model-view-controller web

我目前刚接触Python并且正在学习MVC架构模式。为了简单起见和易于解释,我们说我有3个班级。 (型号,视图和控制器)。

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

  def some_function(self):
    return self.model.add_things(1,2)

class Model
  def __init__(self):
    pass

  def add_things(self, x, y):
    return x + y

class View:
  def __init__(self):
    pass

通常的做法是将我的视图和模型实例化为Controller的实例变量,如上所述?

或者,最好是在Controller文件的顶部手动导入文件(即导入模型)并直接在控制器中调用方法?

from Model import Model 
from View import View

class Controller  
  def __init__(self):
     pass

 def some_function(self):
     return Model.add_things(1, 2)

class Model
  def __init__(self):
    pass

  def add_things(self, x, y):
    return x + y

class View:
  def __init__(self):
    pass

1 个答案:

答案 0 :(得分:1)

我认为你的例子不太适合鼻烟。在您的第二个代码段中,您(可能)仍在处理类(ModelView),,因此这段代码对我来说有点奇怪

from Model import Model 
from View import View

class Controller  

    def some_function(self):
        # How are you calling the method on the class and not the instance?
        return Model.add_things(1, 2)

您必须执行类似return Model().add_things(1, 2)之类的操作才能获取调用add_things方法的实例(除非该函数使用classmethod修饰)。然而,这真的没有任何意义,我敢冒险你可能不是那个意思。您实际上要求的是在构造函数中初始化对象与使用全局声明的实例之间的区别,所以类似这样的

# It seems that for your question, it shouldn't really matter whether the 
# class `Model` is imported or declared inside the same module. So it could 
# be either way.
# 1) class Model(): pass
# 2) from Model import Model    

# This would initialize `Model` at the module-level
modelobject = Model()

class Controller  

    def some_function(self):
        # And then it would be possible to use it as you described.
        return modelobject.add_things(1, 2)

回到问题......

要回答你,我首先要让你意识到你真正要求的是什么重点是,从外部导入ModelView与在他们使用的同一模块中定义它们之间没有任何错误或有争议,所以询问这并没有多大意义;事实上,这实际上取决于你的程序结构,更一般地说,取决于你的项目 big 。越大越复杂,这些类或类集合在同一模块中混合的可能性就越小。他们很快就会被分成不同的模块。

所以,就我所理解的而言,你真正的问题是,是否最好在Model的构造函数中初始化ViewController对象或使用它们作为全局实例,您可以从Controller课程调用。坦率地说,我认为你真正要问的是类似于全局实例模式(例如,类似于Singleton类)。

你没有专门使用术语 Singleton ,但要求一种方法来使用全局声明的类实例,这很像这样你在问什么。

您可以阅读有关其陷阱hereherehere的信息。

更好的方法是Dependency Injection

要引用原始示例,它可能 - 在代码层次结构中较低的对象 - 最好使用以下方法(在整个程序中获取单个实例):

class SubController
    def __init__(self, modelobject, viewobject):
        self.view = viewobject
        self.model = modelobject

换句话说,它与 singleton 不同,因为你实际上是在使用单个实例,如果这确实是你需要的那个。但是,它不是通过声明一个全局实例(它会引入链接和链接文章中讨论的许多其他问题),而是通过让类通过调用上下文获取其依赖性(具有相当大的优点)。因此,您直接通过构造函数方法传递ModelView对象,而不是直接在类中实例化它们(如示例中所示)或使用全局声明的变量获取它们。

当然,您总是拥有 main 类或函数,您可以在其中实例化这些对象并从那里传出它们。这种方法的好处是可以在以后更灵活地使用!