0

I'm used to programming in Java, so my view of these things is quite Java based but I doubt this is the correct way of writing Python code. I found this https://stackoverflow.com/questions/106896/how-many-python-classes-should-i-put-in-one-file link which asks a similar question to what I am about to ask.

In Python, when creating an MVC application, does it make sense to put all the classes in one file (module) as each part of the MVC application does technically belong together?

In Java, the idea would surely be to split these files as we might want to swap out either part of the MVC combination for another part. That is one of the advantages of writing MVC code (though in practice, might happen rarely). Still, I would opt to create a file for each part of the MVC code. A class for the model, view and controller.

Now, I can kind of get grouping objectGUI, objectModel, objectController in one module. As together they form object. But on the other hand, that feels kind of wrong from the Java background.

Is there a good rule of thumb for how splitting into modules actually works in Python. Is MVC even a strong thing in Python? (In my mind, Python is still mostly for glue code and scripts).

3

In Python, a file is a unit of import. So it makes sense to put things that belong together in the same file, and things that don't, to separate files.

Web frameworks like Django by default expect you to put your models in models.py, and your views / controllers in views.py. In large applications, these files are actually split, usually by subject area. Django also allows you to compose a whole web app from several reusable 'applications', each with its own structure.

It is easy to split a large file into several files without breaking existing code in Python. You just re-export the names from a split-out file, like this:

(views.py)

# These used to be defined here, now moved to premium_views.py 
from premium_views import FancyFeatureView, ExtraSnazzyView

class StandardView(...): ...

Now you can from views import FancyFeatureView, as if it were completely defined there. There's even a pattern of having such files that only re-export things from a bunch of other modules, so that these other modules can be changed as authors see fit without affecting normal client code.

Another consideration could be testing. What you want to test under significantly different setups likely belongs to different modules (files).

  • I disagree - in python the unit of import is the module which is either a single file or a directory structure containing __init__.py, either can be built &/or compressed into an .egg or wheel. – Steve Barnes Apr 12 '17 at 6:38
  • Oh thank you. Your example of views does make sense from the point of view that they are all "views" so you can pick which one you need. But I suppose that in Java I might be more tempted to group the views more closely to the domain they belong to. – Dylan Meeus Apr 12 '17 at 8:05
  • @SteveBarnes: this is fair. A file is a unit of import; other, more complex units exist, as you noted. – 9000 Apr 12 '17 at 13:57
  • @DylanMeeus: you can group things as you see fit; Python is more flexible in this regard than Java. Python lacks the strict Java-style package structure with canonical names; you can adhere to it if you want to (use absolute imports), or not. If you want to group views by domain, you're free to do so, either by putting them all in the same multi-file package, or in the same file. One important note: it's an anti-pattern for a deeper-level module to import something directly from its ancestors; it's prone to circular import errors. Importing from sister packages is OK. – 9000 Apr 12 '17 at 14:02
  • 1
    @DylanMeeus - While circular imports are something to avoid wherever possible python is actually very well tolerant of circular dependencies - module initialisation only occurs on the first import of a module. The main reason to avoid them is that it becomes a nightmare when re-factoring. – Steve Barnes Apr 12 '17 at 16:34
1

In python you can use the modules structure to group files by functionality and to control what is normally available. A module is a directory with several python files, and potentially sub-modules, and must contain a __init.py__ file. This file can be used to control the public interface of the module.

If you have a module, containing an __init.py__ file, called fred then you can import fred and access its members as fred.item_name or from fred import item_name then use item_name.

It is important to note the python practice of having, in each file, a section beginning with:

if __name__ == "__main__":

The code within the scope of this if statement will be executed only if that file is invoked directly - this allows modules to contain executable standalone utilities while still being importable as libraries by other modules or for providing standalone tests at the file or module level.

It is important to note that when the individual files in a module or the whole module are imported into a higher level item they will be byte compiled from .py to .pyc files which speeds up subsequent imports and general performance, (on the first import of any session or run the time stamps are checked between identically named .py to .pyc files to check if recompilation is needed).

  • 1
    Thank you for your reply and also for your explanation about the init.py. I am extremely new to Python and did not know this :-) – Dylan Meeus Apr 12 '17 at 8:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.