Back to Blog
Python

python if __name__ == '__main__': How It Works

python if **name** == "**main**": Learn how the `if __name__ == "__main__":` guard works, why it prevents import side effects, and when to use it in Python scripts.

python__name__module executionscript entry pointimport guard
Illustration of a Python script file being split into an importable module and a direct execution entry point, with a guard condition separating them.

python if name == "main" requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

In Python, the line if __name__ == "__main__": is a guard that distinguishes between running a file directly and importing it as a module. This article explains what __name__ actually contains, why the guard prevents unwanted side effects, and how to use it correctly in scripts and modules.

What __name__ Contains During Execution

Every Python module has a built-in global variable named __name__. Its value depends on how the module is being executed:

  • When you run a file directly with python file.py, Python sets __name__ to the string "__main__".
  • When you import that same file from another module, __name__ is set to the module's fully qualified name, such as "package.module".

The guard if __name__ == "__main__": checks this variable. If the condition is true, the code inside the block runs only when the file is the entry point of the program.

# example.py print("module name:", __name__) if __name__ == "__main__": print("executed directly")

Running python example.py prints:

module name: __main__ executed directly

Importing it from another script prints only the module name:

import example
module name: example

The code inside the guard does not run on import. This is the core behavior that makes the guard useful.

Why the Guard Prevents Import Side Effects

When you import a module, Python executes every top-level statement in that file. If you put startup logic—like opening files, connecting to databases, or starting a server—at the top level, that logic runs on import. That is rarely what you want.

Consider a utility module that also contains a test harness:

# utils.py def calculate_total(items): return sum(item.price for item in items) # This runs on import, which is usually undesirable print("utils module loaded")

Any module that imports utils will see that print statement and any other side effects. Wrapping the print inside the guard prevents it from running on import:

# utils.py def calculate_total(items): return sum(item.price for item in items) if __name__ == "__main__": print("utils module loaded")

Now the print only appears when utils.py is run directly. This keeps the module clean for importers and gives you a convenient way to test the module in isolation.

Using the Guard for CLI Entry Points

The most common pattern is to define a main() function and call it inside the guard. This keeps the logic reusable and testable while still providing a command-line interface.

# cli_tool.py import sys def main(argv): if len(argv) < 2: print("Usage: cli_tool.py <name>") return 1 print(f"Hello, {argv[1]}!") return 0 if __name__ == "__main__": sys.exit(main(sys.argv[1:]))

Here main() accepts the argument list, which makes it easy to call from tests without relying on sys.argv. The guard ensures that main() runs only when the file is executed directly, not when imported.

This pattern also works with argparse or any other argument parser. The guard simply wraps the call that triggers the parser.

Common Mistakes and Misconceptions

One frequent mistake is forgetting the guard entirely. If you have a script that performs real work at the top level, importing it from another script will trigger that work unexpectedly. This can cause duplicate execution, side effects, or hard-to-debug errors.

Another misconception is that the guard is required for every module. If a module is never meant to be imported, you can skip the guard, but it is still good practice to include it. It costs nothing and makes the file's behavior explicit.

Some developers also assume that __name__ is set to "__main__" only in the file that starts the program. That is true, but the guard works even if the file is part of a package. When you run python -m package.module, Python sets __name__ to "__main__" for that module as well.

When You Might Not Need the Guard

For a simple one-off script that will never be imported, the guard is optional. If the script is only run directly, the top-level code executes as intended. However, adding the guard costs one line and protects against future imports.

Interactive environments like Jupyter notebooks or REPL sessions do not use the guard the same way. In a notebook, each cell runs in a shared namespace, and __name__ is set to "__main__" for the kernel. The guard may not behave as expected if you are mixing cell execution with imports. In those contexts, it is better to structure the notebook cells to avoid the guard altogether.

Edge Cases and Compatibility

The guard works in all Python 3 versions. In Python 2, the same behavior applies, though the syntax is identical. No special imports are needed.

One edge case occurs when a module is executed with python -m. The __name__ is set to "__main__", so the guard works. But if the module is part of a package and you run python -m package.module, the module's __name__ is still "__main__" inside that module. This allows you to use the guard to provide a package-level entry point.

Another subtlety is that __name__ can be changed programmatically. Libraries like multiprocessing may set __name__ to "__mp_main__" when spawning child processes on Windows. This is a known quirk: the guard will not trigger in those child processes because __name__ is not "__main__". If you rely on the guard to run initialization in every process, you need to handle that separately. For most scripts, this is not an issue, but it is worth knowing if you use multiprocessing with a guarded main block.

Structuring Modules for Testability

Putting the bulk of logic in functions and calling them from the guard makes the module testable. You can import the module in a test file and call the functions directly without triggering the script's entry point.

# calculator.py def add(a, b): return a + b def subtract(a, b): return a - b if __name__ == "__main__": print(add(5, 3)) print(subtract(5, 3))

A test file can do:

from calculator import add, subtract assert add(2, 2) == 4 assert subtract(5, 1) == 4

The guard prevents the test output from appearing during import. This separation between definition and execution is the primary maintainability benefit of the pattern.

python if **name** == "**main**": Practical Usage and Code E | RYUSLOG DEV