Use __main__.py

We have all seen the __init__.py file and know its role, but what is __main__.py? I have seen many Python projects either on Github or at work that do not take advantage of this magic file. In my opinion, including a __main__.py is a better way to interface with multi-file python modules.

But first some background: How do most people run their Python programs?

Occasionally you will write a program that is organized enough so that it can both be imported as a module to another program or run by itself through a command line interface. In this case, you are probably familiar with the following lines commonly placed at the bottom of the file:

if __name__ == '__main__':
    main(sys.argv)

When you run a program by calling the Python interpreter on it, the magic global variable __name__ gets set to __main__. We can use that to know that we are not being imported as a module, but ran. For example:

python myapp.py

This works just fine for single file projects.

The problem

If you are like me, you do not want your entire application in a single python file. Separating related logic out into their own files makes for easier editing and maintainability. For example:

.
├── README.me
├── requirements.txt
├── setup.py
└── src
    ├── __init__.py
    ├── client.py
    ├── logic.py
    ├── models.py
    └── run.py

But then this raises confusion to a user who just downloaded your program. Which one is the main file? Is it run.py? Or maybe client.py? What file has my precious if __name__ == ‘__main__’ statement? This is where we can get a lot of value from __main__.py.

__main__.py

The magic file __main__.py is called when you run your project with the -m module flag. If you code is intended to be used a module first, and command line interface second, this makes perfect sense to use. Think of it as a place we can put whatever would be in our body of our if __name__ == __main__ statement. Refactoring the project above to conform:

.
├── README.me
├── requirements.txt
├── setup.py
└── myapp
    ├── __init__.py
    ├── __main__.py
    ├── client.py
    ├── logic.py
    ├── models.py

And now we just run it as a module not a singleton program.

python -m myapp

__main__.py will auto-magically be executed. This is a perfect place to put a command line interface and handle program arguments!

Good luck and happy hacking!

7 thoughts on “Use __main__.py

  1. Great post! Any suggestions on the following?

    1. How to organize common code when you have a suite of apps with each app being a package?

    2. Where to place your test (pytest) code when you have multiple apps managed as packages, eg. under each package or within a separate tests package with sub-packages for each app level package?

    3. Your thoughts on using a src folder to separate development versions of packages from installed versions of packages?

    Thank you!

    1. Hi

      1. One solution, have one App be named “yourproject_utils” or “yourproject_core” and have it as a dependency to every other App.
      2. In its ok package as a sibling to your “src”. I know Django puts a test.py in each package (and sub packages). That is ok too.
      3. Good idea!

  2. It’s a good idea… before you try to cover code of __main__ with tests. Then you return to a very simple code in this file which calls a function form another module. And in this situation it’s easier to write the common pattern with condition rather than do additional work to exclude logic from this file and this file from tests.

Leave a Reply

Your email address will not be published. Required fields are marked *