A module is a file of Python code that other files can use. We’ve already imported a few — math, random, json, csv, pathlib. This lesson covers what import actually does and the four ways to write it.
The basic form — import module
import math
print(math.sqrt(16)) # 4.0
print(math.pi) # 3.141592653589793
import math makes the entire math module available under the name math. To use anything from it, you write math.something.
Importing specific names — from module import name
from math import sqrt, pi
print(sqrt(16)) # 4.0
print(pi) # 3.141592653589793
from math import sqrt brings just sqrt into your file. No math. prefix needed.
When to use which:
import math— when you’ll use many names from the module, or when you want it obvious where they came from.from math import sqrt— when you only use one or two specific things from it.
Both are good Python.
Renaming on import — as
If a module’s name is long, or two modules use the same name, rename with as:
import numpy as np
arr = np.array([1, 2, 3])
np is the universally agreed nickname for NumPy. Same for import pandas as pd and import matplotlib.pyplot as plt. Don’t invent your own — stick to community conventions.
You can also rename specific imports:
from pathlib import Path as P # not common, but works
Star imports — avoid
You can import everything from a module:
from math import *
print(sqrt(16)) # 4.0
print(pi) # 3.14...
Don’t do this in scripts. It dumps every name into your file, making it impossible to tell where things came from and risking name collisions. Almost every linter (including Ruff) flags from x import *.
The one place it’s accepted: inside a package’s __init__.py to re-export public names. We’ll skip that detail.
Where Python looks for modules
When you write import foo, Python searches a list of directories called the module search path. In order:
- The directory of the script you ran.
- Folders in the
PYTHONPATHenvironment variable. - The standard library locations (where
math,json, etc. live). - Your virtual environment’s
site-packagesfolder (whereuv addputs third-party packages).
You can see the search path:
import sys
print(sys.path)
In practice, you don’t think about this. Inside a uv project, everything just works — the venv’s site-packages is automatically on the path.
Modules are loaded once
The first time you import a module, Python runs the file top to bottom. Subsequent imports return the same module object — it’s not run again. This is why importing is fast.
# my_module.py
print("module loaded")
counter = 0
# main.py
import my_module # prints "module loaded"
import my_module # nothing — already loaded
import my_module # still nothing
Useful to know when debugging: the file actually executes during the first import.
Standard library and third-party imports
By convention, group your imports in this order, with a blank line between each group:
# 1. standard library
import json
import sys
from pathlib import Path
# 2. third-party packages
import numpy as np
import pandas as pd
# 3. your own modules
from my_project import helpers
from my_project.models import User
Ruff (with I rules turned on) sorts this automatically.
Common standard library modules
A taste of what comes built in:
math,statistics— maths and basic statisticsrandom— random numbersdatetime— dates and timesjson,csv,tomllib— data formatspathlib,os,sys— filesystem and OScollections,itertools,functools— more data toolsre— regular expressionsurllib,http— basic HTTP and URLs
We’ll tour the most useful in Section 14.
What’s next
You can use modules other people wrote. Next, how to write your own — and import them from somewhere else.