Skip to the solution
EasyBackend12 min read

What does if __name__ == "__main__" do?

860 views

The problem

Question presented to candidate: "You see if __name__ == "__main__": at the bottom of almost every Python script. What does that line actually check, and what would break if you deleted it?"

What a strong answer should cover:

  • Every module has a global __name__. The interpreter sets it to "__main__" for the module it was started with (python file.py, python -m pkg.mod, python -c), and to the module's import name (for example "greet") when the file is imported.
  • So the guard runs its block only when the file is executed as the program, not when another module imports it; the rest of the file (functions, classes, constants) still runs on import.
  • Why it matters: importing a module should have no side effects β€” tests, tools and other modules can import the functions without starting the script.
  • Practical cases: multiprocessing with the spawn or forkserver start methods re-imports the main module in each child, so unguarded start-up code runs again; a script that imports itself runs twice as two modules.
  • The idiomatic shape: put the work in def main(argv=None) -> int, and end with if __name__ == "__main__": raise SystemExit(main()); a package uses __main__.py for python -m pkg.

Code / implementation expected: Optional β€” a module with a main() function and the guard, and what prints on import versus on run.

  • modules
  • basics

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

12 min read Β· 11 sections

Run the code

Edit the code and run it here. Each console line with an expected value becomes a test.

PythonImport vs run: the same file, two values of __name__
PythonReal command lines: python file.py, python -m, a package, a self-import
# Real interpreters, real command lines: python file.py, python -m, a package.
import os
import subprocess
import sys
import tempfile

root = tempfile.mkdtemp()

def write(rel, text):
    path = os.path.join(root, rel)
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with open(path, "w") as f:
        f.write(text)

def run(*args):
    out = subprocess.run([sys.executable, *args], cwd=root,
                         capture_output=True, text=True, check=True)
    print("$ python", " ".join(args))
    print(out.stdout, end="")

write("tool.py", '''
import sys
print("tool: __name__ =", __name__, "| spec =", None if __spec__ is None else __spec__.name)
if __name__ == "__main__":
    print("tool: argv[1:] =", sys.argv[1:])
''')

# A script that imports ITSELF: the file runs twice, as two modules.
write("selfimport.py", '''
print("running as", __name__)
import selfimport
''')

# A package with __main__.py, so python -m app works.
write("app/__init__.py", 'print("app/__init__.py runs, __name__ =", __name__)\n')
write("app/__main__.py", 'print("app/__main__.py runs, __name__ =", __name__)\n')

run("tool.py", "--verbose")
run("-m", "tool", "x")
run("-c", "import tool")
run("selfimport.py")
run("-m", "app")
PythonThe idiomatic main() pattern, testable without a subprocess

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 12 of 139 in Python

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Python questions
Up nextEasy

What do *args and **kwargs mean?

Continue