The `__main__.py` File: The Front Door to Your Python Package
If __init__.py is the receptionist that organizes your package, then __main__.py is the front door. It's the specific file Python looks for when you try to execute a directory as if it were a single script.
In 2026, as Python applications become more modular, __main__.py has become the standard way to provide a Command Line Interface (CLI) for your tools.
🚀 What Does It Actually Do?
When you run the command python -m my_package, Python doesn't just look at the folder; it looks for a file named __main__.py inside that folder. If it finds it, it executes the code inside.
Without this file, trying to run a package results in an error:
/usr/bin/python3: No module named my_package.__main__; 'my_package' is a package and cannot be directly executed
💻 The "Scriptable Package" Setup
Here is how you structure a project so it can be run from the terminal.
Folder Structure:
my_app/
├── __init__.py
├── __main__.py <-- The Entry Point
└── logic.py
Inside __main__.py:
This file should act as a "wrapper" that calls your actual application logic.
from .logic import start_engine
def main():
print("Initializing Application...")
start_engine()
if __name__ == "__main__":
main()
How to run it: From the parent directory, you simply type:
python -m my_app
🛠️ __init__.py vs. __main__.py
It's easy to get these two confused. Think of them as having two completely different "triggers."
| File | Triggered By... | Primary Purpose |
|---|---|---|
__init__.py | import my_app | Setup, package-level variables, and API exposing. |
__main__.py | python -m my_app | Execution, CLI handling, and starting the app. |
Note: When you run
python -m my_app, Python actually executes__init__.pyfirst, and then__main__.py. This ensures all your package setup is done before the script starts running.
💡 Why Use __main__.py? (The 2026 Benefits)
1. Cleaner Command Line Tools
Instead of telling users to find a specific file like python my_app/run_this_thing_v2_final.py, you give them a clean package name. This is how famous tools like pip (python -m pip) and venv (python -m venv) work.
2. Avoiding Path Issues
Running a script with -m adds the current directory to Python's search path (sys.path). This solves the "ModuleNotFoundError" that often happens when a script tries to import a sibling file but can't find it.
3. Creating "Executable" Zip Files
Did you know you can zip up a Python package, and if it has a __main__.py inside, you can run the zip file directly?
zip -r my_app.zip my_app/
python my_app.zip # This actually works!
🛡️ Best Practice: Keep it Lean
Just like __init__.py, don't put your entire 2,000-line application inside __main__.py.
The Golden Rule: __main__.py should only handle argument parsing (using argparse or click) and calling the main function. Keep the actual business logic in your other modules. This makes your code much easier to unit test.
📚 Sources & Technical Refs
- [1.1] Python Docs: main - Top-level script environment - Official reference for the
__main__module. - [2.1] Real Python: What is main.py? - A guide on entry points and script execution.
- [3.1] Python Packaging User Guide: Creating Executable Zips - How to use
__main__.pyfor distribution.
