Modules and imports

Python · Essentials · 8 min

Real programs span many files and lean heavily on Python's 'batteries included' standard library.

Any .py file is a module, and its name is the file name without .py. A directory of modules (usually with an __init__.py) is a package. import makes another module's names available:

  • import math then math.sqrt(2) — keeps the namespace explicit
  • from math import sqrt, pi — imports specific names
  • import numpy as np — an alias, common for long or conventional names
  • from package.sub import thing — dotted paths into packages

Avoid from module import *; it dumps unknown names into your namespace and hides where things come from.

A module's top-level code runs once, the first time it's imported in a process; later imports reuse the cached module object from sys.modules. That's why the if __name__ == "__main__": guard matters — it keeps script-only code from running on import.

Python finds modules by searching sys.path, which starts with the directory of the script you ran, then the standard library, then installed third-party packages. Naming your own file random.py or json.py shadows the standard module and causes baffling errors.

The standard library covers a lot before you need to install anything: pathlib and os for files, json and csv for data, datetime, re for regular expressions, collections and itertools for data wrangling, logging, argparse for command-line tools, random, statistics and many more.

Conventionally, imports go at the top of the file: standard library first, then third-party, then your own modules.

Example

# geometry.py would contain:  def circle_area(r): ...
import math
import json
from datetime import date
from collections import Counter as Tally
import random as rnd

print(math.sqrt(16), math.pi)          # 4.0 3.141592653589793
print(date(2026, 1, 1).isoformat())    # 2026-01-01

data = json.loads('{"lang": "python", "version": 3.13}')
print(data["lang"])                    # python

print(Tally("banana").most_common(1))  # [('a', 3)]
rnd.seed(1)
print(rnd.randint(1, 6))               # same value on every run

Remember

  • Every .py file is a module; directories of modules are packages
  • Module code runs once per process; later imports reuse it
  • Don't name your files after standard modules

Watch out for

  • Shadowing a stdlib module with your own file of the same name.
  • Using from x import *.

Check yourself

  1. A file `app.py` executes `import helpers` twice (in two different functions). How many times does helpers.py's top-level code run?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/tutorial/modules.html