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 maththenmath.sqrt(2)— keeps the namespace explicitfrom math import sqrt, pi— imports specific namesimport numpy as np— an alias, common for long or conventional namesfrom 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 runRemember
- 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 *.