Python · Intermediate
Modules and Imports in Python
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
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.
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.
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
importCounter 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.
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 doesOutput
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
| Statement | How you use it | Notes |
|---|---|---|
| import math | math.sqrt(9) | keeps the origin visible; the default choice |
| import textwrap as tw | tw.fill(text) | alias for a long or clashing name |
| from math import sqrt | sqrt(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.pyormath.pyin 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 underif __name__ == "__main__":.Python · fixdef 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.
# 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
.pyfile;importruns it once and binds its namespace to a name. import m,from m import nameandimport m as aliasare the three forms; avoidfrom 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.
items = int(input())
per_box = int(input())
print(items // per_box)47 ↵ 124import math
items = int(input())
per_box = int(input())
print(math.ceil(items / per_box))Practise this
Exercises for this lesson are in the Python practice set.
Related lessons
- Functions in PythonHow to define and call Python functions with def, pass arguments, return results, use default and keyword arguments, and why variables inside are local.9 min
- Reading and Writing Files in PythonHow to read and write text files in Python with open and with: file modes, reading line by line, appending, explicit encodings, and pathlib for paths.9 min
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.
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.