0%

42- Understanding __name__

The special variable that tells a module how it was executed. The key to making modules both reusable and runnable.

Every module in Python has a built-in variable called __name__. This variable tells you how the module was executed. Was it run directly as a script? Or was it imported into another module? The value of __name__ changes depending on context. When you run a Python file directly, its __name__ is set to “__main__”. When that same file is imported into another file, its __name__ is set to the module’s name (the filename without the .py extension). This simple mechanism is the foundation of a powerful pattern: making code that can be both a reusable module and a standalone script. The if __name__ == “__main__”: guard is one of the most common idioms in Python programming.

🕯️ 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.

What is __name__?
__name__ is a special variable that Python creates automatically for every module. Its value depends on how the module is being used.

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

💡 The double underscores on both sides of __name__ indicate that it is a “special” or “magic” variable. It is set by Python, not by you.
The __main__ Guard
The most common use of __name__ is to check if a module is being run directly. This allows you to put test code or example usage inside the guard.

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.

Running a Module as a Script
When you run a Python file directly, its __name__ becomes “__main__”. This is true whether you run it by filename or as a module with -m.

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”)

The __name__ of Imported Modules
When you import a module, Python sets its __name__ to the module’s name (the filename without .py).

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!

Module-Level Code Execution
Code at the module level (not inside functions or classes) runs immediately when the module is imported. This is why the __main__ guard is important.

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()}”)

⚠️ Be careful with print statements and heavy computations at the module level. They will run every time the module is imported, even if you only want one function from it. Move test code inside the __main__ guard.
Practical Example: A Dual-Purpose Module
Here is a complete example of a module designed to be both a reusable library and a command-line tool.

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()

Using __name__ for Module Testing
The __main__ guard is the standard place for unit tests and examples.

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.

Running a Package as a Script
You can also make a package executable by adding a __main__.py file inside the package directory.

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

__name__ in Different Contexts
Here is how __name__ behaves in different scenarios.
Context__name__ Value
Script run directly (python script.py)“__main__”
Module imported (import module)Module name (e.g., “module”)
Package __init__.pyPackage name (e.g., “my_package”)
Module inside packageFull 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

Common Mistakes with __name__
  • 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

Check Your Understanding
  • 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.

Related posts