Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

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

Sponsored

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

  1. Python starts — you run python myapp.py. The Python interpreter opens myapp.py and begins executing top-level statements from top to bottom.
  2. Python sets __name__ — before executing any code in myapp.py, Python sets __name__ to '__main__' for that file.
  3. 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).
  4. Guard condition — the typical pattern if __name__ == '__main__': checks that value. If true, Python runs the indented block (e.g., a main() 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 be False, 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 the if block for self-reference. __name__ is already set.
  • Multiple __main__-style checks in a module: Only one should exist. Having multiple if __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 .py files you run directly. If you run a zip file or a compiled C extension, the behavior differs.
  • Packages: __name__ in __init__.py of a package is set to the package's name (e.g., 'mypackage'), not '__main__', unless you run the __init__.py directly — 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

  1. Instead of calling main() directly, some developers use __main__.py in a package to define the entry point for python -m package_name.
  2. You can combine if __name__ == '__main__' with argparse to handle command-line arguments for CLI tools.
  3. 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.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.