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:

  1. The directory of the script you ran.
  2. Folders in the PYTHONPATH environment variable.
  3. The standard library locations (where math, json, etc. live).
  4. Your virtual environment’s site-packages folder (where uv add puts 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 statistics
  • random — random numbers
  • datetime — dates and times
  • json, csv, tomllib — data formats
  • pathlib, os, sys — filesystem and OS
  • collections, itertools, functools — more data tools
  • re — regular expressions
  • urllib, 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.

Toggle theme (T)