Course topics

By WebNest Studio Engineering Team

Python Tutorial

Python Modules and the import Statement

A module in Python is simply a file ending in ".py" that contains functions, classes, and variables you want to reuse. The moment you save a Python file, you have created a module — there is no special syntax needed to "declare" one, unlike some other languages that require explicit module keywords.

Modules exist to solve a very practical problem: as programs grow, keeping everything in one file becomes unmanageable. Splitting code into modules lets you organize related functionality together, reuse code across multiple programs without copy-pasting, and keep each file focused on a single responsibility.

Why it matters

No real program is a single file. Modules are how code is split into files and reused, and every import line you write depends on how Python finds and loads them. Most "No module named ..." errors, and code that runs unexpectedly when a file is imported, are explained by the few rules in this lesson.

The import Statement

Python offers several forms of the import statement, and each has a slightly different effect on your namespace.

  • import module_name — imports the whole module; you access its contents with module_name.thing.
  • import module_name as alias — imports the module under a shorter name, commonly seen as import numpy as np.
  • from module_name import thing — imports one specific name directly into your namespace, so you can call it without the module prefix.
  • from module_name import * — imports everything public from the module; generally discouraged because it makes it unclear where a name came from and can silently overwrite existing names.

The Module Search Path

When you write import something, Python does not search your entire filesystem — it searches a specific, ordered list of locations stored in sys.path. This list includes the directory of the script being run, the directories listed in the PYTHONPATH environment variable, and the standard library's installation directories. Python checks each location in order and uses the first matching module it finds, which is why a file you accidentally name the same as a standard library module (like naming your own script "math.py") can "shadow" the real one and cause confusing errors.

if __name__ == "__main__":

Every module has a built-in variable called __name__. When a file is run directly (e.g. python script.py), Python sets __name__ to the string "__main__" for that file. When the same file is instead imported by another module, __name__ is set to the module's actual name instead. This lets you write code that only runs when the file is executed directly — such as test code or a command-line entry point — while still allowing the file's functions and classes to be safely imported elsewhere without that code running.

Examples

A reusable module with a guarded entry point

Python
# file: mathutils.py
def square(n):
    return n * n

def cube(n):
    return n * n * n

if __name__ == "__main__":
    # This block only runs when mathutils.py is executed directly,
    # not when another file imports it.
    print("Testing mathutils module:")
    print(square(4))
    print(cube(3))
Output
Testing mathutils module:
16
27

Importing that same module from another file (the guarded block does not run)

Python
# file: main.py
import mathutils
from mathutils import cube as cb

print(mathutils.square(5))
print(cb(2))
print(__name__)
Output
25
8
__main__

Common Mistakes

  • Naming a personal script the same as a standard library module (e.g. "random.py" or "email.py"), which shadows the real module and causes baffling import errors.
  • Using "from module import *" in real projects, making it unclear which module a given name actually came from and risking silent name collisions.
  • Forgetting the "if __name__ == '__main__':" guard, so test or demo code runs automatically every time the file is imported elsewhere.
  • Assuming "import module_name" re-reads the file every time it is imported — Python actually caches modules in sys.modules after the first import, so top-level code in a module runs only once per process.

Exercise

Use three forms of import: import one name from math, import statistics under the alias stats, and then print the name of the current module.

Expected output: 12.0, 4, __main__ (one per line)

Python · starter code
# TODO: import sqrt from the math module
# TODO: import the statistics module with the alias stats

# TODO: print the square root of 144
# TODO: print the mean of [2, 4, 6]
# TODO: print the value of __name__
Show hints
  • The forms are from math import sqrt and import statistics as stats.
  • A file that is run directly has __name__ equal to "__main__".
Show solution
Python · solution
from math import sqrt
import statistics as stats

print(sqrt(144))
print(stats.mean([2, 4, 6]))
print(__name__)

Quick quiz

1. A module is imported in three different files of the same program. How many times does its top-level code run?

  • A. Three times
  • B. Never
  • C. Once; later imports reuse the loaded module
  • D. Once per function call
Show answer

C. The loaded module is kept in sys.modules and reused.

2. Why is from module import * discouraged?

  • A. It is slower
  • B. It imports nothing
  • C. It does not work in Python 3
  • D. It brings in every public name, which can silently replace names you already have
Show answer

D. It also hides where each name came from.

3. Which list holds the folders that Python searches for modules?

  • A. sys.path
  • B. os.path
  • C. sys.modules
  • D. PATH
Show answer

A. It starts with the folder of the script, then the standard library and installed packages.

Interview questions

What happens when Python executes an import statement?

Show answer

Python first checks sys.modules; if the module is already loaded, that object is reused. Otherwise it searches the folders in sys.path, runs the module's code from top to bottom once, stores the resulting module object in sys.modules, and binds a name to it in the importing file.

What is the difference between "import module" and "from module import name"?

Show answer

import module binds the module itself, and its contents are used as module.name, which shows where each name comes from. from module import name binds that one name directly in the current file, so it is used without a prefix. The whole module is loaded in both cases; only the names made available differ.

Key Points to Remember

  • Any .py file is automatically a module; no special declaration syntax is required.
  • import, import ... as, and from ... import ... each affect your namespace differently.
  • Python resolves imports using sys.path, checking the script directory, PYTHONPATH, and the standard library in order.
  • __name__ equals "__main__" only when a file is run directly, which is the basis of the standard entry-point guard.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs Python in your browser. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering