Skip to content
Python Modules & Packages Explained — Complete Guide with Examples

Python Modules & Packages Explained — Complete Guide with Examples

DodaTech Updated Jun 4, 2026 9 min read

Modules are Python files that contain reusable code, while packages are directories of modules that help organize larger projects. As your programs grow, splitting code into modules keeps it manageable and shareable.

What You’ll Learn

  • How to import built-in, third-party, and your own modules
  • How to create and use your own Python modules
  • How to use pip to install packages from PyPI
  • What virtual environments are and why they’re essential
  • Standard library highlights — os, json, datetime, collections, and more
  • Common module and package mistakes to avoid

Why Modules Matter

Imagine writing a 10,000-line program in a single file. Finding a bug would be like finding a needle in a haystack. Modules let you split code into focused files — like organizing a toolbox into separate drawers. Durga Antivirus Pro has separate modules for signature scanning, behavioral analysis, quarantine management, and logging. DodaZIP has modules for compression algorithms, file I/O, and user interface. Modules are how real software is built.

    flowchart LR
    A["Python Basics"] --> B["Control Flow"]
    B --> C["Functions"]
    C --> D["Lists & Dicts"]
    D --> E["Modules & Packages"]
    E --> F["File I/O & Errors"]
    A:::done --> B:::done --> C:::done --> D:::done --> E:::current --> F
    style A fill:#2563eb,stroke:#2563eb,color:#fff
    style B fill:#2563eb,stroke:#2563eb,color:#fff
    style C fill:#2563eb,stroke:#2563eb,color:#fff
    style D fill:#2563eb,stroke:#2563eb,color:#fff
    style E fill:#2563eb,stroke:#2563eb,color:#fff
    style F fill:#dbeafe,stroke:#2563eb,color:#1e40af
  
Prerequisite: You should understand functions and collections. If those are new, review https://tutorials.dodatech.com/programming-languages/python/py-functions/ and https://tutorials.dodatech.com/programming-languages/python/py-lists-dicts/ first.

What are Modules and Packages?

Think of a module as a single recipe card. It contains instructions for one specific dish. A package is a recipe box — a folder that holds multiple related recipe cards (modules) plus a table of contents (__init__.py).

    flowchart TB
    subgraph Your Project
        A["main.py"] -->|import| B["myutils.py (module)"]
        A -->|import| C["math (stdlib)"]
        A -->|import| D["requests (third-party)"]
    end
    subgraph Python Standard Library
        C
        E["os, json, datetime, ..."]
    end
    subgraph Third-Party
        D
        F["numpy, flask, django, ..."]
    end
  

Importing Modules

# Import the whole module
import math
print(math.sqrt(16))  # 4.0
print(math.pi)        # 3.14159...

# Import specific items (cleaner for frequent use)
from random import randint, choice
print(randint(1, 10))         # Random integer 1-10
print(choice(["a", "b", "c"])) # Random choice

# Import with alias (shortens repeated use)
import datetime as dt
now = dt.datetime.now()
print(now.year)

Which import style should you use?

  • import module — good when you use many functions from that module
  • from module import item — good when you use one or two items frequently
  • from module import *avoid (imports everything, causes name clashes)

Your Own Module

Any .py file is a module. Create myutils.py:

# myutils.py
def greet(name):
    return f"Hello, {name}!"

PI = 3.14159

Use it in another file in the same directory:

# main.py
import myutils
print(myutils.greet("Alice"))  # Hello, Alice!
print(myutils.PI)              # 3.14159

Python searches for modules in the current directory first, then in standard library paths, then in site-packages (where pip installs third-party code).

Standard Library Highlights

Python’s “batteries included” philosophy means many useful modules come built-in.

File & OS Operations

import os
import glob

print(os.getcwd())       # Current directory path
os.makedirs("new_dir", exist_ok=True)

for file in glob.glob("*.py"):
    print(file)

Dates & Times

from datetime import datetime, timedelta

now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M"))

tomorrow = now + timedelta(days=1)
print(tomorrow)

JSON — Data Exchange Format

import json

data = {"name": "Alice", "age": 25}
json_str = json.dumps(data, indent=2)  # Python dict → JSON string
print(json_str)

parsed = json.loads(json_str)          # JSON string → Python dict
print(parsed["name"])

Collections — Advanced Data Structures

from collections import Counter, defaultdict

# Count items
colors = ["red", "blue", "red", "green", "blue", "blue"]
counts = Counter(colors)
print(counts)  # Counter({'blue': 3, 'red': 2, 'green': 1})

# Default dict — no KeyError
scores = defaultdict(list)
scores["Alice"].append(85)
scores["Bob"].append(92)
print(scores["Charlie"])  # [] (no error!)

Statistics

import statistics

data = [2, 5, 3, 8, 5, 7, 4]
print(statistics.mean(data))    # 4.857...
print(statistics.median(data))  # 5
print(statistics.stdev(data))   # 2.035...

pip — Installing Third-Party Packages

The Python Package Index (PyPI) has over 500,000 packages. pip is the tool to install them:

# Install a package
pip install requests

# Install specific version
pip install requests==2.31.0

# List installed packages
pip list

# Uninstall
pip uninstall requests

# Install from requirements file
pip install -r requirements.txt

Using the requests Package

import requests

response = requests.get("https://api.github.com")
data = response.json()
print(response.status_code)  # 200

Virtual Environments

Virtual environments isolate dependencies so each project has its own packages. Think of them as separate workspaces — you can have one project using Flask 2.x and another using Flask 3.x without conflict.

# Create a virtual environment
python -m venv venv

# Activate (Linux/Mac)
source venv/bin/activate

# Activate (Windows)
venv\Scripts\activate

# Once activated, pip installs packages inside the environment:
pip install requests

# Save exact versions for reproducibility
pip freeze > requirements.txt

# On another machine, install everything at once:
pip install -r requirements.txt

# Deactivate when done
deactivate
    flowchart LR
    subgraph System Python
        A[Package A v1.0]
        B[Package B v1.0]
    end
    subgraph Project 1 venv
        C[Package A v2.0]
        D[Package C v1.0]
    end
    subgraph Project 2 venv
        E[Package A v1.5]
        F[Package D v2.0]
    end
  

Packages — Organising Modules into Directories

A package is a directory containing modules and a special __init__.py file:

my_package/
    __init__.py
    utils.py
    models.py
# Import from a package
from my_package import utils
from my_package.models import User

The __init__.py file can be empty. It tells Python the directory should be treated as a package.

Common Mistakes

1. Circular Imports

If module_a.py imports from module_b.py and module_b.py imports from module_a.py, Python raises an ImportError. Fix: Restructure your code — move shared logic to a third module.

2. Name Collision with Standard Library

# Don't name your file math.py!
import math  # imports YOUR file, not the standard library

Fix: Never name your files after standard library modules (math.py, json.py, datetime.py).

3. Forgetting to Activate the Virtual Environment

pip install requests   # installs globally, not in your venv!

Fix: Check your terminal prompt shows (venv) before running pip. Activate first.

4. Committing venv to Version Control

The venv/ directory is large (20-50 MB) and platform-specific. Fix: Add venv/ to .gitignore. Share requirements.txt instead.

5. Using from module import *

from math import *   # imports everything — confusing!

Fix: Use explicit imports: from math import sqrt, pi. Makes code more readable.

6. Not Pinning Dependency Versions

# In requirements.txt:
requests
# Next month: requests 3.0 breaks your code!

Fix: Use pip freeze > requirements.txt to capture exact versions.

Practice Questions

1. What’s the difference between a module and a package?

A module is a single .py file. A package is a directory containing multiple modules and an __init__.py file.

2. Why do we need virtual environments?

To isolate dependencies per project. Without them, installing a package for one project could break another that needs a different version.

3. What does pip freeze > requirements.txt do?

It saves the exact versions of all installed packages to a file. Anyone can run pip install -r requirements.txt to recreate the same environment.

4. How does Python find modules when you import them?

Python searches sys.path — which includes the current directory, standard library paths, and site-packages (where pip installs third-party packages).

Challenge: Create a package called fileutils/ with two modules: reader.py (with a function read_lines(filename) that returns a list of non-empty lines) and writer.py (with a function write_dict(filename, data) that saves a dict as JSON). Then use both from a main.py.

Solution
# fileutils/reader.py
def read_lines(filename: str) -> list:
    with open(filename, "r") as f:
        return [line.strip() for line in f if line.strip()]

# fileutils/writer.py
import json
def write_dict(filename: str, data: dict) -> None:
    with open(filename, "w") as f:
        json.dump(data, f, indent=2)

# main.py
from fileutils.reader import read_lines
from fileutils.writer import write_dict

FAQ

What's the difference between a module and a package?
A module is a single .py file. A package is a directory containing multiple modules and an __init__.py file.
Why do I need a virtual environment?
Virtual environments isolate dependencies per project. Without them, installing a package for one project could break another project that needs a different version.
What does pip freeze > requirements.txt do?
It saves the exact versions of all installed packages to a file. Anyone can then run pip install -r requirements.txt to recreate the same environment.
Why shouldn't I use 'from module import *'?
It imports all public names into your namespace, making it hard to tell where a name came from. It can also silently overwrite existing names. Always import explicitly.
How does Python find modules when I import them?
Python searches the directories in sys.path — which includes the current directory, standard library paths, and site-packages (where pip installs third-party packages).

Try It Yourself

Run this to see modules in action:

import math
import statistics
from datetime import datetime

data = [12, 15, 18, 22, 25, 30, 35]

print(f"Mean: {statistics.mean(data)}")
print(f"Median: {statistics.median(data)}")
print(f"Std Dev: {statistics.stdev(data):.2f}")
print(f"Pi: {math.pi:.4f}")
print(f"Now: {datetime.now().strftime('%H:%M')}")

Expected output:

Mean: 22.428571428571427
Median: 22
Std Dev: 7.91
Pi: 3.1416
Now: 14:35

Mini Project: System Information Report

Build a script that collects system info using only Python’s standard library:

import os
import platform
import sys
import json
from datetime import datetime

def get_system_info() -> dict:
    info = {
        "report_date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "os": platform.system(),
        "os_version": platform.version(),
        "machine": platform.machine(),
        "processor": platform.processor(),
        "python_version": sys.version,
        "current_dir": os.getcwd(),
        "user": os.environ.get("USER", "unknown"),
        "files_in_dir": len(os.listdir(".")),
    }
    return info

def save_report(info: dict, filename: str = "system_report.json") -> None:
    with open(filename, "w") as f:
        json.dump(info, f, indent=2)
    print(f"Report saved to {filename}")

def print_report(info: dict) -> None:
    print()
    print("=" * 50)
    print("          SYSTEM INFORMATION REPORT")
    print("=" * 50)
    for key, value in info.items():
        label = key.replace("_", " ").title()
        print(f"{label:<20}: {value}")
    print("=" * 50)

report = get_system_info()
print_report(report)
save_report(report)

Expected output (example):

==================================================
          SYSTEM INFORMATION REPORT
==================================================
Report Date          : 2026-06-05 11:30:00
Os                   : Linux
Os Version           : #1 SMP ...
Machine              : x86_64
Processor            : x86_64
Python Version       : 3.11.4 (main, ...)
Current Dir          : /home/user/project
User                 : admin1
Files In Dir         : 12
==================================================
Report saved to system_report.json

What’s Next

Now understand modules and move on to file I/O and error handling.

TopicDescriptionLink
Python File I/O & ErrorsRead, write, and handle errorshttps://tutorials.dodatech.com/programming-languages/python/py-io/
Python Lists & DictsMaster Python collectionshttps://tutorials.dodatech.com/programming-languages/python/py-lists-dicts/
DjangoWeb framework built with packagesDjango

Practice tip: Extend the system report project with network info (platform.node() for hostname, socket.gethostbyname() for IP). Then create a package called myutils/ with separate modules.

What’s Next

Congratulations on completing this Py Modules tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro