Python's __main__ Entry Point
Learn how Python uses the `__main__` entry point to control script execution, with practical steps and troubleshooting tips for progressive Python mastery.
Focus: understand python's __main__ entry point
Ever written a Python script that worked perfectly when you ran it directly, only to behave unexpectedly when you imported its functions from another file? That confusion often stems from not understanding Python's __main__ entry point. In this lesson, you'll demystify how Python determines whether a file is the main program or a module being imported, and you'll learn the standard pattern to control execution cleanly.
The problem this lesson solves
When you write a Python script, you usually add a few function definitions and then some code that calls them. If you later import that script from another module, Python runs all the top-level code in the imported file at import time. That can cause side effects like printing debug output, starting infinite loops, or even deleting files — all unintentionally. The core problem: Python doesn't natively know whether you're running a file directly or importing it. You need a reliable way to let a script behave differently in those two scenarios. The if __name__ == '__main__' idiom is that mechanism.
Core concept / mental model
Think of every Python file as a program with two possible roles: main (the star of the show) or module (a supporting actor). Python sets a special built-in variable called __name__ for each file. When you run a file directly with python myscript.py, Python assigns '__main__' to that file's __name__. When the same file is imported (import myscript), Python sets __name__ to the file's actual module name (e.g., 'myscript').
Pro tip:
__name__is a string, not a function or keyword. You can print it to see which role a file is playing at any time.
So the mental model is: __name__ is a door label — when the label reads '__main__', the script is running as the entry point. When it reads something else, the script is being used as a module.
How it works step by step
- Python starts — you run
python myapp.py. The Python interpreter opensmyapp.pyand begins executing top-level statements from top to bottom. - Python sets
__name__— before executing any code inmyapp.py, Python sets__name__to'__main__'for that file. - Code runs — all variable assignments, function definitions, and class definitions are executed. Functions and classes are defined but not yet called (unless there's a direct function call at the top level).
- Guard condition — the typical pattern
if __name__ == '__main__':checks that value. If true, Python runs the indented block (e.g., amain()function). If false (the file was imported), the block is skipped.
The mechanism is built into the Python interpreter — you don't need to import anything special. The __name__ attribute exists in every module's namespace automatically.
Hands-on walkthrough
Let's create a simple calculator script to see the idiom in action.
Example 1: Basic guard pattern
# calculator.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
if __name__ == '__main__':
print('Running directly as the main program')
print('3 + 4 =', add(3, 4))
print('10 - 7 =', subtract(10, 7))
When you run python calculator.py, you'll see:
Running directly as the main program
3 + 4 = 7
10 - 7 = 3
Now import it from another script:
# use_calc.py
import calculator
print('In use_calc, importing calculator')
result = calculator.add(5, 2)
print('Result:', result)
In use_calc, importing calculator
Result: 7
Notice that the guard block did not run — no "Running directly" message appears. That's because when import calculator executed, __name__ inside calculator.py was 'calculator', not '__main__'.
Example 2: Using a main() function
A common best practice is to put your entry-point logic inside a function named main():
# app.py
def calculate_average(numbers):
return sum(numbers) / len(numbers)
def main():
data = [4, 8, 15, 16, 23, 42]
avg = calculate_average(data)
print(f'The average is {avg}')
if __name__ == '__main__':
main()
This structure keeps your module clean: functions are reusable, and the main() function is only called when you run the file directly.
Example 3: What happens without the guard?
# mistake.py
print('This always runs on import or direct execution!')
def greet(name):
return f'Hello, {name}'
print('Now greet:', greet('World'))
If you run python mistake.py, you get:
This always runs on import or direct execution!
Now greet: Hello, World
If you import mistake from another file, you see the same two lines — the module prints during import, which is almost never desired.
Compare options / when to choose what
| Approach | When to use | Pros | Cons |
|---|---|---|---|
if __name__ == '__main__': |
Universal, always preferred | Prevents side effects on import, clean separation | Requires discipline to write |
| No guard | Quick scripts never imported | Less typing | Side effects on import, breaks reusability |
if __name__ == '__main__': + main() |
Professional/reusable modules | Encourages decomposition, testable | Slightly more code |
if __name__ == '__main__': + argparse |
CLI tools with arguments | Adds command-line parsing | Overkill for simple scripts |
Choose the guard always. Even for one-off scripts, the habit will save you from bugs later. Use main() for any module you might import in the future.
Troubleshooting & edge cases
- Typo in the condition:
if __name__ == "main":(missing underscores) — the condition will always beFalse, so your program appears to do nothing when run directly. Remember: two underscores on each side. - Importing the same module inside the guard: You don't need to
import <module>inside theifblock for self-reference.__name__is already set. - Multiple
__main__-style checks in a module: Only one should exist. Having multipleif __name__ == '__main__'blocks inside the same file is valid but confusing — keep it at one at the bottom. - Files without extension: Python only sets
__name__ = '__main__'for.pyfiles you run directly. If you run a zip file or a compiled C extension, the behavior differs. - Packages:
__name__in__init__.pyof a package is set to the package's name (e.g.,'mypackage'), not'__main__', unless you run the__init__.pydirectly — which is rare.
What you learned & what's next
Now you understand how Python's __name__ variable controls script entry points. You can:
- Explain why
if __name__ == '__main__'is essential for reusable modules. - Apply the
main()function pattern to organize your scripts. - Avoid side effects when importing a file that was intended to be run directly.
- Troubleshoot common mistakes like missing underscores or misplaced guard blocks.
Next step: In the upcoming lesson, you'll explore how to pass command-line arguments to your Python scripts using sys.argv, giving your programs even more flexibility and user interaction.
Practice recap
Create a new file helper.py with a function that returns a greeting. Add a main() function that asks the user for their name and prints a message. Use the __name__ guard to run main() only when the file is executed directly. Then import helper from a second script and confirm no output appears on import.
Common mistakes
- Forgetting the double underscores on both sides (
__name__and__main__) — a single underscore or missing underscore makes the condition always False. - Putting
if __name__ == '__main__'at the top of the file instead of the bottom — function definitions must exist before they can be called in the guard block. - Writing code outside the guard block that runs on import, causing unwanted side effects like file writes or network requests during import.
- Thinking
__name__is a function or callable — it's a string variable that you compare with==.
Variations
- Instead of calling
main()directly, some developers use__main__.pyin a package to define the entry point forpython -m package_name. - You can combine
if __name__ == '__main__'withargparseto handle command-line arguments for CLI tools. - Frameworks like Click or Fire can replace the manual
main()pattern while still relying on the__name__guard internally.
Real-world use cases
- A library that provides mathematical functions and also includes a demo script when run directly, showing examples without affecting production imports.
- A data processing script that prints summary statistics when executed directly but exports clean functions for use in a larger ETL pipeline.
- A command-line tool that parses its own arguments and runs only when called directly, keeping its logic testable when imported by a test suite.
Key takeaways
__name__is a built-in string variable set by Python to'__main__'for the directly executed file and to the module name for imports.- Always use
if __name__ == '__main__':to guard code that should not run on import — prevents side effects. - Place the guard at the bottom of the file after all function and class definitions.
- Using a
main()function inside the guard improves code organization and testability. - Missing underscores or typos in the condition are the most common bugs — double-check your underscores.
- The
__name__guard works with any Python file, including scripts, modules, and packages, enabling both importable and executable behavior.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.