Understand if __name__ == "__main__" in Python

Keep command-line execution behind a small entry-point guard while leaving reusable functions safe to import and easy to test.

Best practices
Illustration of software components, data, and application workflows

The guard if __name__ == "__main__": runs its block when the module is executed as the program's top-level entry point. An ordinary import gives the module its import name instead, so that block is skipped.

Compare execution and import

# mylib.py
def say_hi():
    print("Hi from the function")

if __name__ == "__main__":
    print("Running as the entry point")
    say_hi()

python mylib.py prints both lines. import mylib defines say_hi but does not call it. Any top-level statements outside the guard still execute during the first ordinary import, so the guard does not make the whole module free of side effects automatically.

python -m mylib also runs the module as __main__. For an imported package module, the normal name can be qualified, such as package.mylib, rather than just the filename.

Keep the real work in a function

import argparse

def main(argv=None):
    parser = argparse.ArgumentParser()
    parser.add_argument("--name", default="world")
    args = parser.parse_args(argv)
    print(f"Hello, {args.name}")
    return 0

if __name__ == "__main__":
    raise SystemExit(main())

Tests can import this module and call main(["--name", "Ada"]) without parsing pytest's command-line arguments. The guard remains small, and the return code is passed to process exit when used as a script.

Place argument parsing, process startup, or expensive command-line initialization behind that entry point. Small manual smoke checks can live there during development, while a proper test suite provides more repeatable coverage.

Account for multiprocessing startup

With spawn and relevant forkserver workflows, child processes must be able to import the main module safely. Put process creation under the guard to avoid starting more processes while the child imports it. This is a start-method requirement, not just a Windows-specific rule; platform defaults and Python versions differ. Worker functions generally need to be defined at an importable module level.

FAQ

What if I compare with "main" instead?

That is not the entry-point sentinel. A file executed as the program has the value "__main__". A module actually imported under the name main can have __name__ == "main", which is another reason the incorrect comparison is not a reliable entry-point check.

Does a package need this in init.py?

Usually no. Package initialization and command-line execution serve different purposes. python -m package runs the package's __main__.py; keep that entry point small and delegate to reusable code.

How do I test the guarded behavior?

Test the main function directly for most logic. Use a subprocess when you need to verify command-line argument handling, stdout/stderr, or the actual exit status.

References: Python entry points, Python multiprocessing.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting