Python Modules & Packages Explained — Complete Guide with Examples
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
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 modulefrom module import item— good when you use one or two items frequentlyfrom 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.14159Use it in another file in the same directory:
# main.py
import myutils
print(myutils.greet("Alice")) # Hello, Alice!
print(myutils.PI) # 3.14159Python 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.txtUsing the requests Package
import requests
response = requests.get("https://api.github.com")
data = response.json()
print(response.status_code) # 200Virtual 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 UserThe __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 libraryFix: 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_dictFAQ
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:35Mini 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.jsonWhat’s Next
Now understand modules and move on to file I/O and error handling.
| Topic | Description | Link |
|---|---|---|
| Python File I/O & Errors | Read, write, and handle errors | https://tutorials.dodatech.com/programming-languages/python/py-io/ |
| Python Lists & Dicts | Master Python collections | https://tutorials.dodatech.com/programming-languages/python/py-lists-dicts/ |
| Django | Web framework built with packages | Django |
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