🕯️ Magic Note
The __name__ variable is set by the Python interpreter before your code runs. It is part of the import system. Understanding it is essential for writing modules that can be used in multiple ways. Almost every serious Python file uses this pattern.
Python
# File: demo.py
print(f”__name__ is: {__name__}”)
# If you run: python demo.py
# Output: __name__ is: __main__
# If you import from another file: import demo
# Output: __name__ is: demo
Python
# File: calculator.py
def add(a, b):
return a + b
def subtract(a, b):
return a – b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return None
return a / b
if __name__ == “__main__”:
# This code only runs when calculator.py is executed directly
# Not when it is imported
print(“Testing Calculator Module”)
print(f”5 + 3 = {add(5, 3)}”)
print(f”5 – 3 = {subtract(5, 3)}”)
print(f”5 * 3 = {multiply(5, 3)}”)
print(f”5 / 3 = {divide(5, 3)}”)
🕯️ Magic Note
The __main__ guard is essential for module development. It allows you to test your module without affecting code that imports it. It also serves as documentation, showing examples of how to use the module’s functions.
Python
# File: hello.py
def say_hello(name):
print(f”Hello, {name}!”)
if __name__ == “__main__”:
import sys
name = sys.argv[1] if len(sys.argv) > 1 else “World”
say_hello(name)
# Command line usage:
# python hello.py Ali
# Output: Hello, Ali!
# And also importable:
# from hello import say_hello
# say_hello(“Sara”)
Python
# File: my_module.py
print(f”my_module __name__: {__name__}”)
def greet():
return “Hello from my_module!”
# File: main.py
import my_module
print(my_module.greet())
# Output:
# my_module __name__: my_module
# Hello from my_module!
Python
# File: dangerous.py
print(“This runs on import!”)
DATA = [1, 2, 3, 4, 5]
def process_data():
return sum(DATA)
# This print would run every time the module is imported
# Bad if this module is imported many times
# Better:
if __name__ == “__main__”:
# Test code here, not at module level
print(f”Processing result: {process_data()}”)
Python
# File: csv_processor.py
import csv
import sys
def read_csv(filename):
“””Read a CSV file and return a list of dictionaries.”””
data = []
with open(filename, “r”) as f:
reader = csv.DictReader(f)
for row in reader:
data.append(row)
return data
def filter_by_column(data, column, value):
“””Filter data where column equals value.”””
return [row for row in data if row.get(column) == value]
def write_csv(filename, data, fieldnames):
“””Write data to a CSV file.”””
with open(filename, “w”, newline=””) as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
def main():
“””Command-line interface for the module.”””
if len(sys.argv) < 2:
print(“Usage: python csv_processor.py <filename> [–filter column value]”)
sys.exit(1)
filename = sys.argv[1]
data = read_csv(filename)
if “–filter” in sys.argv:
idx = sys.argv.index(“–filter”)
if len(sys.argv) > idx + 2:
column = sys.argv[idx + 1]
value = sys.argv[idx + 2]
data = filter_by_column(data, column, value)
print(f”Found {len(data)} records”)
for row in data[:5]: # Show first 5
print(row)
if len(data) > 5:
print(f”… and {len(data) – 5} more”)
if __name__ == “__main__”:
main()
Python
# File: math_utils.py
def factorial(n):
“””Return n! (n factorial).”””
if n < 0:
raise ValueError(“Factorial not defined for negative numbers”)
if n <= 1:
return 1
return n * factorial(n – 1)
def fibonacci(n):
“””Return the nth Fibonacci number.”””
if n < 0:
raise ValueError(“Fibonacci not defined for negative numbers”)
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
if __name__ == “__main__”:
# Simple tests when run directly
print(“Testing math_utils module…”)
# Test factorial
assert factorial(0) == 1
assert factorial(1) == 1
assert factorial(5) == 120
print(“✓ factorial tests passed”)
# Test fibonacci
assert fibonacci(0) == 0
assert fibonacci(1) == 1
assert fibonacci(6) == 8
print(“✓ fibonacci tests passed”)
print(“All tests passed!”)
🕯️ Magic Note
Using assert statements inside the __main__ guard is a lightweight way to test your module. For larger projects, use dedicated testing frameworks like unittest or pytest.
Python
# Directory structure:
# my_package/
# __init__.py
# __main__.py
# core.py
# File: my_package/__main__.py
from .core import main
if __name__ == “__main__”:
main()
# Now you can run the package as a script:
# python -m my_package
| Context | __name__ Value |
|---|---|
| Script run directly (python script.py) | “__main__” |
| Module imported (import module) | Module name (e.g., “module”) |
| Package __init__.py | Package name (e.g., “my_package”) |
| Module inside package | Full dotted name (e.g., “my_package.submodule”) |
| Interactive interpreter (REPL) | “__main__” |
| Module run with -m (python -m module) | “__main__” |
Python
# Example: Demonstrate __name__ in different contexts
# File: demonstrate.py
print(f”demonstrate.py __name__: {__name__}”)
if __name__ == “__main__”:
print(“This script was run directly”)
else:
print(“This script was imported”)
# Run: python demonstrate.py
# Output:
# demonstrate.py __name__: __main__
# This script was run directly
# Import: import demonstrate
# Output:
# demonstrate.py __name__: demonstrate
# This script was imported
- Forgetting the __main__ guard and having test code run on import
- Using if __name__ == “__main__” inside a function (it is checked at module level, not inside functions)
- Typo: _name_ or __name instead of __name__
- Assuming __name__ is always “__main__” when running a script (it is, but only for the main script)
- Placing import statements inside the __main__ guard (they should be at the top of the file)
Python
# Common mistake: Imports inside main guard
# Bad (imports not available when imported as module)
if __name__ == “__main__”:
import sys
import json
# …
# Good: Imports at the top
import sys
import json
if __name__ == “__main__”:
# Use sys and json here
- What is the value of __name__ when a module is run directly?
- What is the value of __name__ when a module is imported?
- Write a module that can be both imported and run as a script with a main() function.
- Why is the if __name__ == “__main__”: guard important?
- How do you make a package executable as a script?
- What happens if you put test code outside the __main__ guard?
⚡ Whisper
Two underscores before. Two underscores after. __name__ is a small variable with a large role. It watches how the module comes to life. If the module is called to stand alone, __name__ whispers “__main__“. If the module is invited into another’s home, __name__ speaks its given name. This is not a bug. This is a feature. It allows a module to know its context. To act accordingly. To be both a servant (imported) and a leader (run directly). The if __name__ == “__main__”: guard is not just syntax. It is a decision. “If I am in charge, do these things. If I am helping, do not.” This pattern makes modules polite. They do not run test code when imported. They do not print noise unless asked. They are reusable and runnable. They serve multiple purposes. This is the mark of well-designed code. Use it. Every module you write deserves this flexibility.