在Python中布局MVC类

1 投票
2 回答
3129 浏览
提问于 2025-04-16 10:55

我正在做一个Python项目,想要练习一下比较严格的MVC模式。我的想法是把项目分成几个包,分别命名为model(模型)、view(视图)和controller(控制器),每个包里还会有对应的ModelViewController类。每个包里会放一些支持这些部分的文件。

我遇到的问题是,我希望能像这样使用它们:

from controller import Controller

然后在包含控制器类的文件里,我可以:

from controller.someclass import SomeClass

但是如果我把它们放在同名的包里,就会出现问题。我查了一下模块是怎么工作的,发现我需要把它们命名为controller/__init__.pymodel/__init__.pyview/__init__.py,但把它们放在那个文件里感觉有点奇怪,而且在gedit中它们都显示为__init__.py,这让我有点烦。

有没有更好的方法来做到这一点?我这样做是对的吗?

2 个回答

2

如果我理解得没错,你想要的就是让这个事情发生:

from controller import Controller

而不需要在 controller/__init__.py 里定义 Controller 类,对吧?

如果是这样的话,那你只需要这样做:

controller/base.py 里:(注意要有一个叫 base.py 的文件或者其他类似的文件)

class Controller(BaseClass):
  # define Controller here

controller/__init__.py 里:

from base import Controller

现在你就可以得到你想要的确切语法了。

6

我在django的源代码中看到了一些神奇的东西,它能把类从一个叫做base.py的文件中拉到__init__.py的命名空间里。不过我不太清楚这是怎么做到的。(想知道怎么做的话,可以看看评论区。)

根据我所了解的,你可以选择两种方法。

A - 在bar/controller/__init__.py里面

import os,sys
# Make sure the interpreter knows were your files are.
sys.path.append(os.path.join(os.path.dirname(__file__),'../')
from bar.controller import Controller
from bar.model import Model
from bar.view import View
class Controller(object):
 model = Model()
 view = View()

然后你需要创建bar/model/__init__.pybar/view/__init__.py

B - 同样在bar/controller/__init__.py里面

class Model(object):
 pass
class View(object):
 pass
class Controller(object):
 model = Model()
 view = View()

补充:... 在看了你的评论后,我想到第三种选择。其实在python中,包并不一定要直接对应一个模块。我想你想要的结果是创建一个这样的目录结构:

bar/
  __init__.py
  controller.py
  model.py
  view.py

然后在controller.py里面

import os,sys
from bar.controller import Controller
from bar.model import Model
from bar.view import View
class Controller(object):
 model = Model()
 view = View()

这对我来说是个大挑战,因为我之前是从java过来的。你的类文件名不需要和类名一致。可以把它们想象成一个步骤,你先进入文件夹(模块),再进入文件(.py),然后再导入你的类(Model(object))。

撰写回答