Menu
Try in Playground

Python if __name__ == '__main__': The Main Guard, Explained

What if __name__ == '__main__' actually does, why every serious Python script grows into that pattern, and how to structure a file as both a script and a module.

The Weirdest Line in Python — Demystified

Open almost any Python file and you'll eventually see this at the bottom:

if __name__ == "__main__":
    main()

It looks like a bit of magical boilerplate. It's actually a very practical feature once you know what it does — and it exists because Python doesn't draw a line between "scripts" and "libraries."

The Setup: Two Ways to Use a File

Every .py file in Python can be used in two different ways:

  1. As a script — you run it directly with python3 file.py.
  2. As a module — another file imports it with import file.

The language doesn't make you declare which one you're writing. Any file might end up doing both.

Consider a file called math_helpers.py:

# math_helpers.py
def mean(values):
    return sum(values) / len(values)

def median(values):
    s = sorted(values)
    mid = len(s) // 2
    if len(s) % 2 == 0:
        return (s[mid - 1] + s[mid]) / 2
    return s[mid]

# Quick smoke test while developing
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("mean:", mean(numbers))
print("median:", median(numbers))

If you run this file directly, it prints the test output — great. But if some other file does import math_helpers, those print statements run during the import. Every user of the module sees your dev scratch output. Not great.

What __name__ Is

Every Python module has a built-in variable called __name__. Python sets it automatically:

  • When the file is imported, __name__ is set to the module's import name — "math_helpers" in the example above.
  • When the file is run directly, Python sets __name__ to the special string "__main__".

That gives you a way to tell which mode you're in. Wrap the "script-only" code in a check:

# math_helpers.py
def mean(values):
    return sum(values) / len(values)

def median(values):
    s = sorted(values)
    mid = len(s) // 2
    if len(s) % 2 == 0:
        return (s[mid - 1] + s[mid]) / 2
    return s[mid]

if __name__ == "__main__":
    numbers = [3, 1, 4, 1, 5, 9, 2, 6]
    print("mean:", mean(numbers))
    print("median:", median(numbers))

Now python3 math_helpers.py prints the test output. But import math_helpers from another file skips the block entirely — the functions are available, and nothing unwanted runs.

The Common Companion: a main() Function

Most real scripts grow a dedicated main() function and keep the guard block tiny:

# process_orders.py
import sys

def load_orders(path):
    with open(path) as f:
        return [line.strip() for line in f if line.strip()]

def process(orders):
    for order in orders:
        print(f"Processing {order}")

def main():
    if len(sys.argv) < 2:
        print("Usage: python3 process_orders.py <file>")
        sys.exit(1)
    orders = load_orders(sys.argv[1])
    process(orders)

if __name__ == "__main__":
    main()

Why bother with a main() instead of putting the logic directly under the if guard?

  1. Testability. You can import the module and call main() (or any of the helpers) from tests.
  2. Local variables. Anything defined inside main() is a local variable, not a module-level name. That avoids accidental name collisions and makes the module's public surface cleaner.
  3. Readability. The guard block is now two lines — a clear "script entry point" rather than a pile of logic.

A Quick Demonstration

You can see the behavior directly:

main.py
Output
Click Run to see the output here.

When you run the snippet above with Python, it prints __name__ is: __main__ and "being run as a script." If some other file imported this one, the same check would print the other branch.

When You Don't Need the Guard

Plenty of Python files never grow one. Short scripts that nobody would ever import are fine without it:

# one_off_rename.py
import os
for name in os.listdir("."):
    if name.endswith(".txt"):
        os.rename(name, name.lower())

That's perfectly good. You're not building a library; nobody's going to import this. The moment there's reusable logic in a file, though — and you want to keep side-effect code alongside it — reach for the guard.

Entry Points for Installed Packages

Once you're publishing your code as a real package, there's a more formal mechanism: entry_points in your package metadata, which map a command to a function. Users installing your package get a shell command that calls the function directly. But for scripts running out of a folder on your own machine, the __main__ guard is the standard tool.

Wrapping Up This Chapter

You now have:

  • Functions to name your logic.
  • *args/**kwargs for flexible calls.
  • Lambdas for throwaway functions.
  • Decorators and type hints to wrap and document those functions.
  • Modules, pip, and virtual environments to split code across files and projects.
  • The __main__ guard to let scripts and modules coexist.

Next: Classes

You've mostly been pairing functions with plain data — dicts, lists, tuples. The next chapter introduces classes, Python's way of tying data and behavior together, and the place where concepts like self, __init__, inheritance, and dataclasses live.

Frequently Asked Questions

What does if __name__ == '__main__' do?

It only runs the block below it when the file is executed directly (not when the file is imported as a module). This lets you write a .py file that can either be run as a script or imported for its functions and classes — without the script actions happening during import.

Does Python need a main function?

No. Python files run top-to-bottom automatically. But as soon as a file has logic you want to also be importable, the if __name__ == '__main__' guard becomes important — and putting the script's top-level work inside a main() function is a common companion habit.

What's the difference between __name__ and __main__?

__name__ is a special variable Python sets in every module. If the file is imported, __name__ is the module's name (like 'util'). If the file is run directly, Python sets __name__ to the string '__main__'. The if check compares the two.

Learn to code with Coddy

GET STARTED