Site

Modules — Python Modules and Packages

Tutorial 7.0  •  Python / Learn

7.0 What This Teaches

This tutorial covers how Python organizes code with modules and packages:

7.1 What is a Module

A module is simply a .py file. Importing it executes the file once and makes its top-level names available. Every Python source file is automatically a module:
# math_utils.py
PI = 3.14159

def circle_area(r):
    return PI * r * r

def square_area(s):
    return s * s
# main.py
import math_utils

print(math_utils.PI)
print(math_utils.circle_area(3))
After import math_utils, all names from math_utils.py are accessible through the math_utils namespace. The file is only executed once no matter how many times it is imported.

7.2 import and from...import

import math                    # import module; use math.sqrt(...)
import math as m               # alias: m.sqrt(...)
from math import sqrt          # import one name directly
from math import sqrt, pi      # import multiple names
from math import *             # import everything (avoid in production code)

print(math.sqrt(16))   # 4.0
print(m.pi)            # 3.14...
print(sqrt(25))        # 5.0
print(pi)              # 3.14...
Prefer import module over from module import *. The explicit module prefix shows readers where each name comes from and prevents namespace collisions.

7.3 Module Search Path

When you write import foo, Python searches these locations in order:
  1. The directory containing the script being run
  2. Directories in the PYTHONPATH environment variable
  3. The standard library directories
  4. Installed packages in the active virtual environment
import sys
for path in sys.path:
    print(path)
If Python cannot find a module it raises ModuleNotFoundError. Install missing third-party modules with pip install module-name.

7.4 Packages

A package is a directory containing an __init__.py file (which can be empty). Packages let you organize related modules under a namespace:
# directory layout:
# myapp/
#   __init__.py
#   shapes.py
#   utils.py

# shapes.py
class Circle:
    def __init__(self, r): self.r = r
    def area(self): return 3.14159 * self.r ** 2

# main.py
from myapp.shapes import Circle
import myapp.utils as utils

c = Circle(5)
print(c.area())
The __init__.py runs when the package is imported. You can use it to export selected names, making deep imports optional.

7.5 The __name__ Guard

Every module has a __name__ attribute. When a file is run directly, __name__ is "__main__". When imported, it is the module name. Use this to include test code that doesn't run on import:
# geometry.py
def circle_area(r: float) -> float:
    import math
    return math.pi * r * r

if __name__ == "__main__":
    # Only runs when executed directly: python geometry.py
    print(circle_area(3))   # 28.27...
This pattern is idiomatic Python. Libraries use it to include runnable examples or self-tests without polluting the namespace when imported.

7.6 Useful Standard Library Modules

ModulePurposeExample
mathMath functions and constantsmath.sqrt(2)
randomRandom number generationrandom.randint(1, 6)
osOS interaction, pathsos.getcwd()
pathlibObject-oriented pathsPath("data.txt").read_text()
sysInterpreter internals, argvsys.argv[1]
datetimeDates and timesdatetime.now()
jsonJSON encode/decodejson.dumps({"a": 1})
reRegular expressionsre.findall(r"\d+", s)
collectionsCounter, defaultdict, dequeCounter("hello")
itertoolsCombinatorial iteratorsitertools.chain(a, b)

7.7 Example - All Together

# Modules - standard library showcase with math, random, and collections.

import math
import random
import collections

# math: compute statistics manually
values = [random.gauss(0, 1) for _ in range(1000)]
mean = sum(values) / len(values)
variance = sum((v - mean) ** 2 for v in values) / len(values)
print(f"mean={mean:.3f}  std={math.sqrt(variance):.3f}")

# collections.Counter: count word frequencies
words = "the cat sat on the mat the cat".split()
freq = collections.Counter(words)
print(freq.most_common(3))

# pathlib: list current directory's .html files
from pathlib import Path
html_files = sorted(Path(".").glob("*.html"))
print(f"Found {len(html_files)} html files")

7.8 Exercise

Exercise
  • Create a module stats.py with functions mean(data), median(data), and mode(data). Add a __name__ == "__main__" block that tests each function.
  • Import stats from a separate main.py and call all three functions on a list of your choosing.
  • Use random and collections.Counter to simulate rolling two dice 10 000 times and print the frequency of each sum (2-12).

7.9 Common Mistakes

Naming your script the same as a standard library module

# If your file is named math.py:
import math   # imports YOUR math.py, not the standard library
print(math.sqrt(4))   # AttributeError: module 'math' has no attribute 'sqrt'
Never name your files after standard library modules: math.py, os.py, random.py, json.py, etc.

Circular imports

If module A imports module B and module B imports module A, Python can fail with ImportError or silently produce incomplete modules. Refactor shared code into a third module that both import.

Using from module import * in production code

Wildcard imports pollute the local namespace and make it impossible to know where a name comes from without reading the imported module. Reserve them for interactive REPL sessions.

7.10 Key Terms

TermMeaning
moduleAny .py file; imported modules expose their top-level names
packageDirectory with __init__.py; groups related modules under a namespace
importStatement that loads a module and binds its namespace to a name
from...importImports specific names from a module into the current namespace
asCreates an alias for an imported module or name
__name__Built-in attribute; "__main__" when run directly, module name when imported
__init__.pyFile that marks a directory as a package; runs on package import
sys.pathList of directories Python searches when looking for modules
ModuleNotFoundErrorRaised when an import cannot locate the named module
standard libraryModules shipped with Python: math, os, json, collections, etc.