Understanding if __name__ == '__main__' in Python
What is __name__?
Every Python file has a built-in variable called __name__. Python automatically sets its value depending on how the file is being used:
- When you run a file directly (e.g.
python myfile.py), Python sets__name__to the string'__main__'. - When a file is imported by another file, Python sets
__name__to the module’s name (the filename without.py).
This distinction is the foundation of the if __name__ == '__main__': pattern.
The Guard Pattern
if __name__ == '__main__':
# This code only runs when the file is executed directly
print("I am the main program!")
Code inside the guard runs only when the file is the entry point. Code outside the guard runs always — even when the file is imported. This lets you write files that serve double duty: they can be imported as modules and run as standalone scripts.
The Scripts
Let’s walk through four scripts that demonstrate this pattern from the ground up.
Script 1: _01_file.py — Seeing __name__ in Action
print(f'_01_file __name__: {__name__}')
if __name__ == '__main__':
print("Hello from _01_file")
What it does:
- Line 1 runs unconditionally — it always prints the value of
__name__. - Lines 3-4 only execute when the file is run directly.
Run directly:
python _01_file.py
_01_file __name__: __main__
Hello from _01_file
When executed directly, __name__ is '__main__', so the guard condition is True and both print statements fire.
When imported by another file:
import _01_file
_01_file __name__: _01_file
Only the first print() runs. The guard evaluates to False (because __name__ is '_01_file', not '__main__'), so "Hello from _01_file" never prints. We’ll see this in action in the next script.
Script 2: _02_file.py — Import Side Effects
print(f'_02_file __name__: {__name__}')
if __name__ == '__main__':
print("Hello from 02_file")
import _01_file
What it does:
- Prints its own
__name__. - Has its own guarded block.
- Imports
_01_file— and this is where things get interesting.
Run directly:
python _02_file.py
_02_file __name__: __main__
Hello from 02_file
_01_file __name__: _01_file
Walkthrough of the output:
| Line in Output | Who Printed It | Why |
|---|---|---|
_02_file __name__: __main__ |
_02_file.py line 1 |
Directly run, so __name__ is __main__ |
Hello from 02_file |
_02_file.py line 5 |
Guard passed (__name__ was __main__) |
_01_file __name__: _01_file |
_01_file.py line 1 |
Imported, so __name__ is _01_file (not __main__) |
Notice what’s missing: "Hello from _01_file" never appears. Why? Because when _01_file is imported, its __name__ is '_01_file', not '__main__'. The guard in _01_file evaluates to False, and that block is skipped.
This is the whole point. The guard prevents imported modules from executing their “main” logic.
Also note: _01_file.py line 1 (print(f'_01_file __name__: {__name__}')) did run — because it’s outside the guard. Any top-level code outside the if block always executes on import.
Script 3: file_1.py — Reusable Code with Tests
def add(x, y):
return x+y
'''
if add(1, 2) == 3:
print("Pass")
else:
print("Fail")
'''
if __name__ == '__main__':
print('__name__equals__main__')
if add(1, 2) == 3:
print("Pass")
else:
print("Fail")
What it does:
- Defines a reusable
add()function. - Contains a commented-out test block (inside triple quotes
'''...''') — this is dead code, never runs. - Has a guarded print statement.
- Has a test outside the guard — this is important!
Run directly:
python file_1.py
__name__equals__main__
Pass
Both the guarded print and the test execute because the file is run directly.
When imported (by file_2.py):
import file_1
Pass
Wait — "Pass" still prints even on import! That’s because the test at lines 12-15 is outside the if __name__ == '__main__': block. Only line 11 (the guarded print) is protected. Lines 12-15 are top-level code, so they execute every time the module is imported.
This is a common mistake. If you want code to only run when the file is executed directly, it must be inside the if __name__ == '__main__': block, indented under it. The test at lines 12-15 should be indented to be part of the guarded block:
if __name__ == '__main__':
print('__name__equals__main__')
if add(1, 2) == 3:
print("Pass")
else:
print("Fail")
Script 4: file_2.py — Using a Module Cleanly
import file_1
print(file_1.add(1, 2))
What it does:
- Imports
file_1(gaining access to theadd()function). - Calls
file_1.add(1, 2)and prints the result.
Run directly:
python file_2.py
Pass
3
Walkthrough:
| Line | Source | Explanation |
|---|---|---|
Pass |
file_1.py line 12-13 |
Unprotected test code runs on import |
3 |
file_2.py line 3 |
The actual function call we want |
That "Pass" leaking through is the side effect of file_1.py having test code outside the guard. If file_1.py had all its tests properly indented under the if __name__ == '__main__': block, the output would be clean:
3
Mental Model
Running a file directly: python myfile.py
__name__ = "__main__"
Guard passes → main code runs
Importing a file: import myfile
__name__ = "myfile"
Guard fails → main code skipped
Top-level code still runs
Rules to Remember
- Top-level code always executes — whether the file is run directly or imported. This includes function definitions, class definitions, and any statements at the module’s root level.
- Code under the guard only executes when the file is run directly — this is where you put scripts, tests, and demo code.
- Indentation matters — only indented code under
if __name__ == '__main__':is protected. Code at the same level but after the block still runs on import. - The guard is a convention, not a language feature — Python doesn’t enforce it. It’s a widely adopted pattern that makes your files dual-purpose: importable module and runnable script.
When to Use It
- Scripts that can also be imported — utility files that define functions and also have a CLI interface.
- Testing your own modules — put quick tests under the guard so they don’t run when someone imports your code.
- Demonstration code — show example usage that runs when the file is executed but doesn’t pollute the importer’s output.
- Entry points in larger projects —
main.pyorapp.pyfiles that orchestrate the application when run directly.