Python · Intermediate

Modules and Imports in Python

9 min readUpdated September 24, 2026Every example verified

In short: A module is a file of Python code. The import statement loads it once, runs it, and makes its functions, classes and variables available through the module name. The standard library ships hundreds of modules, and your own .py files become modules in exactly the same way.

What a module is and how import works

A module is a .py file. When you write import math, Python searches for a file or package called math, runs its code once, and binds the resulting module object to the name math in your program. Everything the file defined at top level is then reachable as an attribute: math.sqrt, math.pi.

Three forms of import cover almost every need. import statistics keeps the module namespace intact, so the reader always sees where statistics.mean comes from. from collections import Counter copies one name into your namespace. import textwrap as tw shortens a long module name, and the same as works with from: from string import ascii_uppercase as letters.

Python runs a module's code only the first time it is imported in a process. Later imports, even from other files, return the same object from sys.modules. That is why module-level code should define things rather than do things: a module can be imported by ten files without repeating work.

Where Python looks is the list sys.path: the directory of the script you ran, then the standard library, then installed packages. A module in none of those raises ModuleNotFoundError. A file next to your script is therefore importable directly; the third example inserts the folder itself because the checker that runs it starts Python in isolated mode (python -I), which leaves that folder off the path.

Every module has a __name__ variable. In the file you run directly it is the string "__main__"; in a module that was imported it is the module's own name. The idiom if __name__ == "__main__": therefore lets one file act as both a library and a script: its functions can be imported elsewhere without the demonstration code at the bottom running.

The standard library is the collection of modules that ships with Python: math, statistics, collections, string, textwrap, pathlib, json, re, datetime and many more. Reaching for it first saves writing and testing code that already exists, and it needs no installation. dir(module) lists what a module offers, and help(module) prints its documentation.

Syntax

 Python · syntax
import math                      # use as math.sqrt(...)
import textwrap as tw            # shorter alias
from collections import Counter  # bring one name in
from string import ascii_uppercase as letters
from math import floor, ceil     # several names at once

if __name__ == "__main__":       # only when run directly, not when imported
    main()

Put imports at the top of the file, standard library first, so a reader sees every dependency at once.

Using standard-library modules

Sensor readings are summarised with statistics and rounded with math. Every function is reached through its module name.

 Python
import math
import statistics

readings = [12.4, 12.9, 13.1, 12.6, 13.4]
print(statistics.mean(readings))
print(statistics.median(readings))
print(math.ceil(statistics.mean(readings)))
print(math.floor(12.88), math.sqrt(144))
print(round(math.pi, 4))

Output

12.88
12.9
13
12 12.0
3.1416

Neither mean nor ceil is built into Python's core; each lives in a module that must be imported first. Writing statistics.mean rather than a bare mean tells the reader exactly where the function comes from. math.sqrt returns a float even for a perfect square, which is why 144 gives 12.0, and math.pi is a module-level variable, not a function.

from-import and aliases

Three import styles in one program: a single name, a renamed constant and an aliased module.

 Python
from collections import Counter
from string import ascii_uppercase as letters
import textwrap as tw

log = "ok ok fail ok retry fail ok"
counts = Counter(log.split())
print(counts.most_common(2))
print(letters[:5])
print(tw.fill("a module is just a file of python code that you can import", width=30))

Output

[('ok', 4), ('fail', 2)]
ABCDE
a module is just a file of
python code that you can
import

Counter is used without a prefix because from collections import Counter placed that one name in the program's namespace. ascii_uppercase was imported under the shorter name letters, and the whole textwrap module is available as tw. All three refer to the same loaded modules a plain import would use; only the names in your file differ.

Writing your own module and importing it

The program creates pricing.py, imports it twice, then runs it as a script. Watch when the module's code runs and what __name__ is each time.

 Python
import importlib
import os
import runpy
import sys

with open("pricing.py", "w", encoding="utf-8") as f:
    f.write("TAX_RATE = 0.2\n")
    f.write("def with_tax(amount):\n")
    f.write("    return round(amount * (1 + TAX_RATE), 2)\n")
    f.write("if __name__ == '__main__':\n")
    f.write("    print('run as a script:', with_tax(10))\n")
    f.write("else:\n")
    f.write("    print('imported as', __name__)\n")

sys.path.insert(0, os.getcwd())   # make the current folder searchable
importlib.invalidate_caches()     # the file appeared after Python started
import pricing
import pricing                    # already loaded: the file does not run again
print(pricing.with_tax(50))
print(pricing.TAX_RATE)

runpy.run_path("pricing.py", run_name="__main__")   # what python pricing.py does

Output

imported as pricing
60.0
0.2
run as a script: 12.0

The file is an ordinary module: a constant, a function and an if __name__ == '__main__': guard. The first import pricing runs it with __name__ set to pricing, so the else branch prints; the second import finds the module in sys.modules and runs nothing. runpy.run_path(..., run_name="__main__") executes the same file the way python pricing.py would, so the guard is true and the script branch runs. The two setup lines are needed only because the file appeared after Python started and the checker runs Python in isolated mode, which keeps the working folder off sys.path; a pricing.py next to your script imports with no setup.

Import forms

StatementHow you use itNotes
import mathmath.sqrt(9)keeps the origin visible; the default choice
import textwrap as twtw.fill(text)alias for a long or clashing name
from math import sqrtsqrt(9)short, but hides where sqrt came from
from math import *sqrt(9)avoid: floods your namespace with unknown names

Common mistakes

  • Naming your file after a standard-library module

    Why it goes wrong: A file called random.py or math.py in your project folder shadows the real module, because the script's directory is searched first. The resulting errors make no sense until you spot the file name.

    Fix: Choose distinct names for your own files. If a module misbehaves, print module.__file__ to see which file was actually loaded.

  • Using from module import *

    Why it goes wrong: Every public name in the module lands in yours, so two modules can silently overwrite each other's functions and a reader cannot tell where anything came from.

    Fix: Import the module, or list the names you need explicitly.

  • Doing work at the top level of a module

    Why it goes wrong: Top-level code runs on import. A module that prints, reads files or starts a server when imported cannot be used as a library and slows down every importer.

    Fix: Wrap script behaviour in a main() function and call it under if __name__ == "__main__":.

     Python · fix
    def main():
        ...
    
    if __name__ == "__main__":
        main()
  • Two modules importing each other at the top

    Why it goes wrong: A circular import means one module is only half loaded when the other asks for its names, giving ImportError: cannot import name.

    Fix: Move the shared code into a third module both can import, or import inside the function that needs it.

Where you use this

Splitting a growing script into modules is how a program stays understandable. A small reporting tool might have parsing.py for reading the input files, rules.py for the business calculations and report.py for formatting, with a short main.py that imports the three and wires them together. Each file can be tested on its own, and the calculations in rules.py can be reused by a different front end later.

The standard library removes work from the other direction. Before writing a function to compute a median, count occurrences, wrap text or parse a date, check whether statistics, collections, textwrap or datetime already does it, correctly and with edge cases you have not thought of.

 Python · in practice
# main.py
import parsing
import rules
import report

records = parsing.load("orders.csv")
report.print_summary(rules.totals(records))

Key points

  • A module is a .py file; import runs it once and binds its namespace to a name.
  • import m, from m import name and import m as alias are the three forms; avoid from m import *.
  • Python searches the directories in sys.path, starting with the folder of the script you ran.
  • A module's code runs only on the first import; later imports reuse the object in sys.modules.
  • __name__ is "__main__" in the file being run and the module's name everywhere else.
  • The standard library is large and installed with Python; check it before writing your own.

Try it yourself

The program should print how many boxes are needed to ship the items when a box holds per_box items. The current integer division rounds down. Import the math module and use math.ceil so a partly filled box still counts.

Your program
items = int(input())
per_box = int(input())
print(items // per_box)
Input the program receives: 47 ↵ 12
Expected output: 4

Practise this

Exercises for this lesson are in the Python practice set.

Open the Python playground

Frequently asked questions

What is the difference between a module and a package in Python?

A module is a single .py file. A package is a directory containing modules, usually with an __init__.py file, that Python treats as a namespace, so import pkg.module reaches the file pkg/module.py. Packages are how larger projects and libraries organise many modules under one name.

What does if __name__ == "__main__" do?

It checks whether the file is the one Python was told to run. In that case __name__ is "__main__" and the block executes; when the file is imported by another module, __name__ is the module's own name and the block is skipped. It lets one file contain reusable functions plus a script section that only runs on direct execution.

Why does Python say ModuleNotFoundError for a file that exists?

The file is not in any directory listed in sys.path. Python looks in the folder of the script you ran, the standard library and installed packages, not in every subfolder of your project. Move the file next to the script, make its folder a package, or add the directory to sys.path before importing.

Progress is stored only in this browser.

How this page was checked. Every program on it was run with CPython 3.11 at build time; runs in your browser on CPython 3.14 (Pyodide) by the publishing checks, and the output shown is what it printed. The Run buttons execute the same code on your device; nothing you type is sent anywhere.