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.
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.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan