Python
ImportError
Module Initialization
Programming
Code Execution

Why is Python running my module when I import it, and how do I stop it?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When you import a Python module, Python executes all the top-level code in that file — not just function and class definitions, but also print statements, function calls, and any other executable code. This is by design: Python needs to execute the module to define its functions, classes, and variables. To prevent code from running on import, wrap it in if __name__ == "__main__":. This guard checks whether the module is being run directly (as a script) or being imported, and only executes the protected code when run directly.

The Problem

python
1# mymodule.py
2def greet(name):
3    return f"Hello, {name}!"
4
5print("Module loaded!")
6result = greet("World")
7print(result)
python
# main.py
import mymodule  # This prints "Module loaded!" and "Hello, World!"

Running main.py prints both messages because import mymodule executes every line in mymodule.py, including the print calls.

The Fix: if __name__ == "__main__":

python
1# mymodule.py
2def greet(name):
3    return f"Hello, {name}!"
4
5if __name__ == "__main__":
6    # Only runs when this file is executed directly
7    print("Module loaded!")
8    result = greet("World")
9    print(result)
python
# main.py
import mymodule  # No output — the guarded code is skipped
print(mymodule.greet("Alice"))  # "Hello, Alice!"
bash
$ python mymodule.py    # Prints "Module loaded!" and "Hello, World!"
$ python main.py        # Only prints "Hello, Alice!"

How __name__ Works

python
1# When run directly:   __name__ == "__main__"
2# When imported:        __name__ == "mymodule" (the module's name)
3
4# utils.py
5print(f"__name__ is: {__name__}")
6
7def add(a, b):
8    return a + b
9
10if __name__ == "__main__":
11    print(f"Running directly: {add(2, 3)}")
bash
1$ python utils.py
2__name__ is: __main__
3Running directly: 5
4
5$ python -c "import utils"
6__name__ is: utils

Common Use Cases

Script with Importable Functions

python
1# converter.py
2def celsius_to_fahrenheit(c):
3    return c * 9/5 + 32
4
5def fahrenheit_to_celsius(f):
6    return (f - 32) * 5/9
7
8if __name__ == "__main__":
9    import sys
10    if len(sys.argv) != 3:
11        print("Usage: converter.py <temp> <C|F>")
12        sys.exit(1)
13
14    temp = float(sys.argv[1])
15    unit = sys.argv[2].upper()
16
17    if unit == "C":
18        print(f"{temp}°C = {celsius_to_fahrenheit(temp):.1f}°F")
19    elif unit == "F":
20        print(f"{temp}°F = {fahrenheit_to_celsius(temp):.1f}°C")
bash
$ python converter.py 100 C      # 100°C = 212.0°F
python
from converter import celsius_to_fahrenheit
print(celsius_to_fahrenheit(100))  # 212.0 — no CLI output

Running Tests

python
1# mathutils.py
2def factorial(n):
3    if n <= 1:
4        return 1
5    return n * factorial(n - 1)
6
7if __name__ == "__main__":
8    # Quick tests when run directly
9    assert factorial(0) == 1
10    assert factorial(5) == 120
11    assert factorial(10) == 3628800
12    print("All tests passed!")

Entry Point for Packages

python
1# mypackage/__main__.py
2from .core import main
3
4if __name__ == "__main__":
5    main()
bash
$ python -m mypackage  # Executes __main__.py

What Top-Level Code Is Safe to Leave Unguarded

python
1# These are fine at the top level (always executed on import):
2import os
3import sys
4from pathlib import Path
5
6# Constants
7MAX_RETRIES = 3
8DEFAULT_TIMEOUT = 30
9
10# Function definitions
11def process(data):
12    ...
13
14# Class definitions
15class Config:
16    ...
17
18# Module-level initialization that SHOULD run on import
19logger = logging.getLogger(__name__)
20
21# These should be GUARDED:
22if __name__ == "__main__":
23    # CLI argument parsing
24    # print statements for debugging
25    # Function calls that produce side effects
26    # Long-running computations
27    main()

Common Pitfalls

  • Putting initialization code outside the guard: Any print(), input(), database connection, file write, or network request at the top level runs on every import. Move side-effect-producing code inside if __name__ == "__main__":.
  • Importing a module that modifies global state: Some libraries print messages, configure logging, or modify sys.path at import time. If you import such a module, its side effects execute immediately. Check third-party module documentation for import-time behavior.
  • Forgetting the guard when using argparse: parser.parse_args() reads sys.argv and fails when imported in contexts like Jupyter or test runners. Always put argument parsing inside the __name__ guard.
  • Assuming functions are not defined on import: Function and class definitions (def, class) are executed on import — they create function/class objects in the module's namespace. This is the intended behavior. Only guard the code that calls those functions.
  • Using __name__ guard in Jupyter notebooks: In a Jupyter notebook, __name__ is always "__main__" for every cell, so the guard does not help. Structure notebook code differently — use function calls instead of top-level executable code.

Summary

  • Python executes all top-level code in a module when it is imported — including prints, function calls, and variable assignments
  • Use if __name__ == "__main__": to protect code that should only run when the file is executed directly as a script
  • __name__ is "__main__" when run directly and the module's name when imported
  • Function and class definitions should stay at the top level (outside the guard) so they are importable
  • Guard argument parsing, CLI output, tests, and any other side-effect-producing code
  • For packages, use __main__.py to define the entry point for python -m mypackage

Course illustration
Course illustration

All Rights Reserved.