Courses/Python Mastery/Module 10: Power Tools
Module 10 · Lesson 425 minBeginner

Modules, Imports & the Standard Library Tour

Lesson goal
Organize code into files and meet the batteries Python ships with.

Modules, Imports & the Standard Library Tour

Every .py file you've written is already a module — and Python ships with hundreds of ready-made ones. Imports are how you use code from other files, and the standard library is the reason Python is called a "batteries-included" language.

Importing: three forms

You've been importing since lesson one — now the full picture. Say you have a file math_tools.py:

code
# math_tools.py
def add(a, b):
    return a + b

PI = 3.14159

Form 1: import the module (use everything through the module name):

code
import math_tools

print(math_tools.add(2, 3))     # 5
print(math_tools.PI)            # 3.14159

Form 2: import specific names (use them directly):

code
from math_tools import add, PI

print(add(2, 3))      # 5 — no module prefix needed

Form 3: import with a nickname (standard for long names):

code
import math_tools as mt

print(mt.add(2, 3))

You've used all three already: import streamlit as st, from dataclasses import dataclass, import json.

The standard library — batteries included

Every Python installation ships with a massive toolbox. The modules professionals reach for weekly:

ModuleWhat it doesExample
randomrandomnessrandom.randint(1, 6)
datetimedates and timesdatetime.now()
mathadvanced mathmath.sqrt(16)
os / pathlibfiles and foldersos.listdir(".")
jsonJSON datajson.dumps(data)
csvCSV filescsv.reader(f)
collectionsspecialized containersCounter(words)
itertoolsloop superpowersitertools.combinations(...)

A taste of three:

code
import random

print(random.randint(1, 6))          # dice roll
print(random.choice(["a", "b", "c"]))  # random pick
print(random.shuffle(my_list))       # shuffle in place
code
from datetime import datetime, date

now = datetime.now()
print(now.year, now.month, now.day)
print(now.strftime("%d %B %Y"))      # 24 August 2026
code
from collections import Counter

votes = ["a", "b", "a", "a", "c"]
print(Counter(votes))       # Counter({'a': 3, 'b': 1, 'c': 1})
print(Counter(votes).most_common(2))   # [('a', 3), ('b', 1)]

That Counter just replaced the manual word-counting pattern from Module 5 — the standard library often has your problem pre-solved.

Your own files as modules

Split a growing script into files, import between them:

code
# calculations.py
def add(a, b):
    return a + b

def area(r):
    return 3.14159 * r ** 2
code
# main.py
from calculations import add, area

print(add(2, 3))       # 5
print(area(2))         # 12.56636

Both files in the same folder, and main.py can import calculations. This is how apps grow past one file.

The if __name__ == "__main__": mystery, solved

You've seen this line in tutorials. Here's what it means:

code
# calculations.py
def add(a, b):
    return a + b

print("calculations.py is running!")     # runs ALWAYS — even on import!

Import calculations from main.py and that print fires — surprising! The guard fixes it:

code
# calculations.py
def add(a, b):
    return a + b

if __name__ == "__main__":
    print("This only runs when THIS file is run directly")
    print(add(2, 3))

Python secretly sets __name__ to "__main__" when a file is run directly, and to the module's name when it's imported. The guard says: *"demo code only when run directly; silent library when imported."* Every professional Python file uses it.

Common Errors & Fixes

  • `ModuleNotFoundError` — the file isn't in the same folder (or isn't installed). For your own files: same folder. For packages: pip install.
  • `ImportError: cannot import name 'x'` — the name doesn't exist in that module; check spelling or the module's docs.
  • Circular import hang — file A imports B, B imports A. Restructure: shared code goes in a third file both import.
  • Module shadows a stdlib module — naming your file random.py makes import random import YOUR file. Rename yours.

  • ✅ Checkpoint

  • Three import forms? *(import module / from module import name / import module as alias)*
  • What does Counter(["a","a","b"]) give? *(Counter({'a': 2, 'b': 1}))*
  • When does the if __name__ == "__main__": block run? *(Only when the file runs directly — not on import)*
  • Why is naming a file json.py dangerous? *(It shadows the stdlib json module)*
  • Next: 🧪 Practice — a full project setup, venv to API call.