1

I'm working on a project in Python, and I'm trying to follow a somewhat-strict MVC pattern for practice. My idea was to separate things out into packages named model, view and controller, plus have a Model, View and Controller class for each. Each package would have the supporting files for each piece.

My problem is that I want to be able to use them like:

from controller import Controller

And then in the file with the Controller class I can:

from controller.someclass import SomeClass

But if I put them in packages with the same name, I get problems. I read up about how modules work, and realized I needed to name them controller/__init__.py, model/__init__.py and view/__init__.py, but it seems weird to put them in that file, and it's kind of annoying that all of them show up gedit as __init__.py

Is there any better way of doing this? Am I going about this the right way?

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • I think you're missing the point of python modules. Do you need to have classes? Why can't you have your logic in your controller package so you can just do `import controller` and then `controller.whatever()` – Falmarri Jan 31 '11 at 04:10
  • The problem would be the same if I was doing it that way. I'd still be putting a bunch of logic in files named `__init__.py`. – Brendan Long Jan 31 '11 at 04:28
  • Yes, that's how python works. – Falmarri Jan 31 '11 at 05:03
  • See this: http://stackoverflow.com/questions/101268/hidden-features-of-python/4675525#4675525 – Apalala Jan 31 '11 at 23:36

2 Answers2

6

I've seen some black magic in the django source that pulls classes from a base.py file into the __init__.py namespace. However I'm not sure how that's done. ( See comments for how to do this. )

From what I do know, you can do one of two things.

A - inside 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()

And now you make bar/model/__init__.py and bar/view/__init__.py

B - inside bar/controller/__init__.py

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

Edit:... After reading your comment, a third option comes to mind. A package doesn't litertly translate into a module in python. I think your desired result is to create a directory structure like this:

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

Then inside 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()

This was a huge hurdle for me to get coming from java. Your class file names do not have to match the class name. Think of them as a step, you step into the folder(module) and then into the file(.py) and then you import your class.(Model(object))

jbcurtin
  • 1,793
  • 2
  • 14
  • 23
2

If I understand correctly, all you're interested in doing here is having this happen:

from controller import Controller

without having the Controller class defined in controller/__init__.py is that right?

If so, then just do this:

In controller/base.py: (notice there is a file called base.py or something else)

class Controller(BaseClass):
  # define Controller here

In controller/__init__.py:

from base import Controller

Now you can have the exact syntax you are looking for.

Jesse Dhillon
  • 7,841
  • 1
  • 34
  • 34