Python “if __name__ == ‘__main__'”

Every Python file is a module, and every module secretly carries a built-in variable called __name__ that tells it how it is currently being used: run directly as a program, or imported by another file. The line if __name__ == "__main__": is a guard that lets code run only in the first case. It is one of the most common lines you will see near the bottom of real Python scripts, and understanding it is the key to writing files that work both as standalone programs and as reusable, importable modules.

Overview: How Python Assigns __name__

When the Python interpreter loads any .py file, it creates a module object to represent it. That module object gets a set of built-in attributes automatically, and one of the most important is __name__, a string holding the module’s name. What that string actually contains depends entirely on how the file was loaded, not on anything you write in the file itself.

There are two cases:

  • Run directly. When you execute a file from the command line with python script.py (or double-click it, or run it with python -m script), Python treats that file as the entry point of the program. It loads the file into a module and gives that module the special name "__main__" — regardless of what the file is actually called on disk. So inside script.py, __name__ equals the string "__main__".
  • Imported by another file. When some other module does import script, Python still loads and executes script.py from top to bottom (that is how import works — it runs the module body once), but this time the module gets its real name: the string "script", taken from the filename. So inside script.py, __name__ now equals "script", not "__main__".

Because __name__ changes depending on context, you can use it as a condition. Code wrapped in if __name__ == "__main__": only runs when the file is the one that was launched directly — never when it is merely imported as a library by something else. This is essential because import always executes the whole file top to bottom; without the guard, anything at module level (test calls, print statements, opening files, starting a server) would fire every single time anyone imports your module, which is almost never what you want.

It also matters for tooling: the special module name "__main__" is used by Python’s own machinery. For example, sys.modules["__main__"] always refers to whatever script started the process, and the multiprocessing module relies on the guard to avoid infinitely re-spawning child processes on platforms that re-import the main script to create new processes (notably Windows).

Syntax

if __name__ == "__main__":
    # statements here run only when this file is executed directly
    main()
Part Meaning
__name__ Built-in string variable, automatically set by the interpreter for every module.
== Standard equality comparison; returns True or False.
"__main__" The literal string Python assigns to __name__ only when a file is the program’s entry point. Note the double underscores on both sides.
indented block Any code you want to run only in “direct execution” mode — commonly a call to a main() function, argument parsing, or quick self-tests.

Examples

Example 1: Watching __name__ change

This module prints its own __name__ value so you can see the difference between running it directly and importing it.

def greet(name):
    return f"Hello, {name}!"


print(f"__name__ is: {__name__}")

if __name__ == "__main__":
    print(greet("World"))
Output:
__name__ is: __main__
Hello, World!

Because this file was run directly with something like python greeting.py, Python set its __name__ to "__main__". The condition is True, so greet("World") is called and printed. If another file instead wrote import greeting, the print(f"__name__ is: {__name__}") line would still run (because import executes the whole module body) and would show __name__ is: greeting — but the if block would be skipped entirely, so "Hello, World!" would never print.

Example 2: A module used both ways

Here is a small “library” module with its own built-in self-test, plus a second file that imports it. This is the classic real-world pattern.

# File: mathutils.py
def add(a, b):
    return a + b


def subtract(a, b):
    return a - b


def _run_self_tests():
    assert add(2, 3) == 5
    assert subtract(5, 2) == 3
    print("All self-tests passed!")


if __name__ == "__main__":
    _run_self_tests()
# File: app.py
import mathutils

result = mathutils.add(10, 5)
print(f"10 + 5 = {result}")
Output (running: python app.py):
10 + 5 = 15

Running python mathutils.py directly prints All self-tests passed!, because __name__ is "__main__" in that process. But running python app.py only prints 10 + 5 = 15 — the import of mathutils executes its function definitions (so add and subtract become available), but since __name__ inside mathutils.py is now "mathutils", not "__main__", the self-test call never fires. The library behaves differently depending on who is running it, with zero extra code needed on the caller’s side.

Example 3: A realistic command-line script

Real scripts usually put their logic in a main() function and call it from the guard, rather than writing loose top-level statements.

import sys


def calculate_area(radius: float) -> float:
    return 3.14159 * radius ** 2


def main() -> int:
    if len(sys.argv) < 2:
        print("Usage: python circle.py ")
        return 1
    radius = float(sys.argv[1])
    area = calculate_area(radius)
    print(f"Area of circle with radius {radius} is {area:.2f}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
Output (running: python circle.py 5):
Area of circle with radius 5.0 is 78.54

Notice that calculate_area and main are ordinary, testable, importable functions — nothing about them depends on how the file is run. Only the very last two lines are conditional. Another file could do from circle import calculate_area and reuse the math without triggering the command-line argument parsing or the sys.exit call at all. This separation of “reusable logic” from “script behavior” is exactly what the guard is for.

How It Works Step by Step

  1. You type python script.py at the command line.
  2. The interpreter starts a fresh process and needs a name for the file it is about to run, so it creates a module object and sets its __name__ attribute to the string "__main__" before executing anything.
  3. Python then executes the file’s statements from top to bottom, in order, exactly as written — function and class definitions are compiled and bound to names, and any top-level statements (including your if __name__ == "__main__": check) run immediately as they are reached.
  4. When execution reaches the if __name__ == "__main__": line, Python evaluates the comparison. Since __name__ is "__main__", the condition is True, so the indented block underneath runs.
  5. If instead another script had done import script, Python would check sys.modules first (to avoid re-running an already-imported module), then, on first import, execute the same file top to bottom — but this time it sets __name__ to "script" (derived from the filename) before running it. The if condition becomes False, and the guarded block is skipped, while every function and class defined above it is still available on the imported module object.

Common Mistakes

Mistake 1: Forgetting the guard entirely

Writing script-only logic at the very top level of a file with no guard means it runs on every import, not just direct execution:

def process(data):
    return [x * 2 for x in data]

result = process([1, 2, 3])
print(result)

If another module does import this_file, the print(result) line fires immediately as an unwanted side effect — surprising output, wasted computation, or worse (opening files, connecting to a database) happening just because someone imported your code. The fix is to move the logic into a function and only call it inside the guard:

def process(data):
    return [x * 2 for x in data]


def main():
    result = process([1, 2, 3])
    print(result)


if __name__ == "__main__":
    main()

Mistake 2: Misspelling the comparison string

The special string has two underscores on each side of main. A typo like if __name__ == "main": is valid Python — it will not raise an error — but the condition will always be False, because __name__ is never simply "main". The guarded block silently never runs, and it can be confusing to debug because there is no traceback to point at the mistake:

def main():
    print("Running main")


if __name__ == "main":  # missing double underscores on both sides!
    main()
Output:
(nothing is printed)

Double-check the string is exactly "__main__", or better, rely on your editor’s syntax highlighting and autocompletion, which usually catches this.

Best Practices

  • Put the executable logic of a script inside a function (conventionally named main()), and call only that function from inside the guard — keeps the module importable and testable.
  • Place the if __name__ == "__main__": block at the very bottom of the file, after all function and class definitions, so readers see the reusable API first and the “how to run this” logic last.
  • Use sys.exit(main()) when main() returns an exit code, so the process reports success (0) or failure (non-zero) correctly to the shell.
  • Never rely on the guard for security or to “hide” code — it only controls whether code runs automatically, not whether it can be imported and called by name.
  • When writing multiprocessing code on Windows (or anywhere using the spawn start method), always guard the code that creates Process objects with if __name__ == "__main__":, since child processes re-import the main script and would otherwise re-trigger process creation infinitely.
  • Keep the guarded block small — a call to main() plus argument handling is usually enough; heavy logic belongs in testable functions above it.

Practice Exercises

  1. Create a module temperature.py with a function celsius_to_fahrenheit(c) and a guarded block that prints the result for 25 degrees Celsius only when the file is run directly. Then write a second file that imports just the function and confirm the guarded print statement does not run.
  2. Take a script that currently has loose top-level statements (no functions, no guard) and refactor it so all logic lives inside a main() function, called only under if __name__ == "__main__":.
  3. Without running any code, predict what print(__name__) would output if placed at the top level of a file named utils.py in two situations: (a) running python utils.py directly, and (b) another file executing import utils. Write down both answers, then verify your reasoning against the Overview section above.

Summary

  • __name__ is a built-in string attribute that every Python module gets automatically.
  • When a file is run directly, Python sets its __name__ to "__main__"; when the same file is imported, __name__ becomes the module’s real name instead.
  • if __name__ == "__main__": lets you write code that only executes on direct execution, not on import.
  • Importing a module always runs its top-level code once — the guard is what prevents script-only behavior (self-tests, CLI parsing, prints) from firing during that import.
  • The idiomatic pattern is to put real logic in functions (like main()) and call them from inside the guard, keeping the file both a usable script and a clean, importable library.
  • The guard is also required for correct multiprocessing behavior on platforms that re-import the main script to spawn child processes.