Skip to main content

Module 7 - Modules & Packages

This module covers modules and packages in Python. You'll learn how to organize code, import modules, create your own modules, and understand Python's package system.


1. What are Modules?

1.1 Understanding Modules

A module is a Python file containing definitions and statements. Modules help organize code into logical units.

# Example: math module
import math

print(math.pi) # 3.141592653589793
print(math.sqrt(16)) # 4.0
print(math.ceil(4.3)) # 5

1.2 Why Use Modules?

  • Code organization: Group related functionality
  • Reusability: Import code across projects
  • Namespace management: Avoid name conflicts
  • Maintainability: Easier to manage large codebases
Module vs Script

A module is imported and used by other code. A script is executed directly. A Python file can be both!


2. Importing Modules

2.1 Basic Import

# Import entire module
import math
print(math.sqrt(25))

# Import multiple modules
import math, random, os

# Import with alias
import numpy as np
import pandas as pd

# Import specific items
from math import pi, sqrt, ceil
print(pi)
print(sqrt(25))

# Import all (avoid in production)
from math import *
print(cos(0))

2.2 Import Styles

# Style 1: Import module
import math
result = math.sqrt(16)

# Style 2: Import with alias (preferred for long names)
import numpy as np
array = np.array([1, 2, 3])

# Style 3: Import specific items
from math import sqrt, pi
result = sqrt(16)

# Style 4: Import with renaming
from math import sqrt as square_root
result = square_root(16)
Avoid Wildcard Imports

Don't use from module import * in production code. It pollutes the namespace and makes code harder to understand.

2.3 Relative vs Absolute Imports

# Absolute import (from project root)
from myproject.utils.helpers import validate
from myproject.models.user import User

# Relative import (within same package)
from .helpers import validate # Same directory
from ..models.user import User # Parent directory
from ...config import settings # Two levels up

3. Creating Your Own Modules

3.1 Simple Module

# File: mymath.py
"""
A simple math utilities module.
"""

def add(a, b):
"""Add two numbers."""
return a + b

def subtract(a, b):
"""Subtract b from a."""
return a - b

def multiply(a, b):
"""Multiply two numbers."""
return a * b

PI = 3.14159

# Using the module
# File: main.py
import mymath

print(mymath.add(5, 3)) # 8
print(mymath.PI) # 3.14159

3.2 Module with Classes

# File: calculator.py
class Calculator:
"""A simple calculator class."""

def __init__(self):
self.result = 0

def add(self, value):
self.result += value
return self

def subtract(self, value):
self.result -= value
return self

def get_result(self):
return self.result

# Using the module
# File: main.py
from calculator import Calculator

calc = Calculator()
result = calc.add(10).subtract(3).get_result()
print(result) # 7

4. The name Variable

4.1 Understanding name

# File: mymodule.py
print(f"Module name: {__name__}")

def greet():
print("Hello from mymodule!")

# This runs only when executed directly
if __name__ == "__main__":
print("Running as main program")
greet()

# When imported: __name__ = "mymodule"
# When run directly: __name__ = "__main__"

4.2 Practical Usage

# File: utils.py
def process_data(data):
"""Process data."""
return [x * 2 for x in data]

def main():
"""Main function for testing."""
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Result: {result}")

if __name__ == "__main__":
main()

# Can be imported without running main()
# import utils
# Or executed directly
# python utils.py
Best Practice

Always use if __name__ == "__main__": for code that should only run when the file is executed directly, not when imported.


5. Packages

5.1 What is a Package?

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

mypackage/
├── __init__.py
├── module1.py
├── module2.py
└── subpackage/
├── __init__.py
└── module3.py

5.2 Creating a Package

# Directory structure
myproject/
├── __init__.py
├── math_utils/
│ ├── __init__.py
│ ├── basic.py
│ └── advanced.py
└── string_utils/
├── __init__.py
└── formatter.py

# File: math_utils/basic.py
def add(a, b):
return a + b

def subtract(a, b):
return a - b

# File: math_utils/advanced.py
def power(base, exponent):
return base ** exponent

def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)

# File: math_utils/__init__.py
from .basic import add, subtract
from .advanced import power, factorial

__all__ = ['add', 'subtract', 'power', 'factorial']

# Using the package
from myproject.math_utils import add, power
print(add(5, 3)) # 8
print(power(2, 3)) # 8

5.3 init.py File

# File: mypackage/__init__.py

# Import submodules
from . import module1
from . import module2

# Import specific items
from .module1 import function1
from .module2 import Class1

# Define what gets exported with "from package import *"
__all__ = ['function1', 'Class1', 'module1', 'module2']

# Package-level variables
__version__ = "1.0.0"
__author__ = "Your Name"

# Package initialization code
print(f"Initializing mypackage version {__version__}")

6. Standard Library Modules

6.1 Commonly Used Modules

# os - Operating system interface
import os
print(os.getcwd()) # Current directory
print(os.listdir('.')) # List files
os.mkdir('new_folder') # Create directory

# sys - System-specific parameters
import sys
print(sys.version) # Python version
print(sys.path) # Module search path
sys.exit() # Exit program

# datetime - Date and time
from datetime import datetime, timedelta
now = datetime.now()
print(now)
tomorrow = now + timedelta(days=1)

# random - Random numbers
import random
print(random.randint(1, 10)) # Random integer
print(random.choice(['a', 'b', 'c'])) # Random choice
random.shuffle([1, 2, 3, 4, 5]) # Shuffle list

# json - JSON encoding/decoding
import json
data = {"name": "Alice", "age": 25}
json_string = json.dumps(data)
parsed = json.loads(json_string)

6.2 Collections Module

from collections import Counter, defaultdict, namedtuple, deque

# Counter
words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']
count = Counter(words)
print(count) # Counter({'apple': 3, 'banana': 2, 'cherry': 1})
print(count.most_common(2)) # [('apple', 3), ('banana', 2)]

# defaultdict
from collections import defaultdict
word_lengths = defaultdict(list)
for word in ['apple', 'banana', 'cherry']:
word_lengths[len(word)].append(word)
print(dict(word_lengths)) # {5: ['apple'], 6: ['banana', 'cherry']}

# namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 10 20

# deque (double-ended queue)
from collections import deque
d = deque([1, 2, 3])
d.append(4) # Add to right
d.appendleft(0) # Add to left
print(d) # deque([0, 1, 2, 3, 4])

6.3 Itertools Module

import itertools

# count - Infinite counter
for i in itertools.count(10, 2):
if i > 20:
break
print(i) # 10, 12, 14, 16, 18, 20

# cycle - Cycle through iterable
colors = itertools.cycle(['red', 'green', 'blue'])
for _ in range(5):
print(next(colors)) # red, green, blue, red, green

# combinations
letters = ['A', 'B', 'C']
print(list(itertools.combinations(letters, 2)))
# [('A', 'B'), ('A', 'C'), ('B', 'C')]

# permutations
print(list(itertools.permutations(letters, 2)))
# [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]

# chain - Combine iterables
numbers1 = [1, 2, 3]
numbers2 = [4, 5, 6]
combined = list(itertools.chain(numbers1, numbers2))
print(combined) # [1, 2, 3, 4, 5, 6]

7. Module Search Path

7.1 How Python Finds Modules

import sys

# Python searches in this order:
# 1. Current directory
# 2. PYTHONPATH environment variable
# 3. Standard library directories
# 4. Site-packages (third-party packages)

print(sys.path) # List of directories

# Add custom path
sys.path.append('/path/to/my/modules')
sys.path.insert(0, '/priority/path') # Add at beginning

7.2 PYTHONPATH

# Set PYTHONPATH (Linux/Mac)
export PYTHONPATH=/path/to/modules:$PYTHONPATH

# Set PYTHONPATH (Windows)
set PYTHONPATH=C:\path\to\modules;%PYTHONPATH%

# Permanent (add to .bashrc or .bash_profile)
echo 'export PYTHONPATH=/path/to/modules:$PYTHONPATH' >> ~/.bashrc

8. Third-Party Packages

8.1 Installing Packages with pip

# Install package
pip install requests

# Install specific version
pip install requests==2.28.0

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

# Upgrade package
pip install --upgrade requests

# Uninstall package
pip uninstall requests

# List installed packages
pip list

# Show package details
pip show requests

# Generate requirements file
pip freeze > requirements.txt

8.2 requirements.txt

# requirements.txt
requests==2.28.0
pandas>=1.4.0
numpy~=1.23.0
flask
pytest>=7.0,<8.0

9. Virtual Environments

9.1 Why Virtual Environments?

  • Isolate project dependencies
  • Avoid version conflicts
  • Easy project setup
  • Reproducible environments

9.2 Creating Virtual Environments

# Create virtual environment
python -m venv myenv

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

# Activate (Windows)
myenv\Scripts\activate

# Deactivate
deactivate

# Delete virtual environment
rm -rf myenv # Linux/Mac
rmdir /s myenv # Windows

9.3 Using Virtual Environments

# Create project structure
mkdir myproject
cd myproject
python -m venv venv

# Activate
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows

# Install packages
pip install requests pandas

# Generate requirements
pip freeze > requirements.txt

# Setup on another machine
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Best Practice

Always use virtual environments for Python projects. Add venv/ or .venv/ to .gitignore.


10. Package Structure Best Practices

myproject/
├── README.md
├── setup.py
├── requirements.txt
├── .gitignore
├── tests/
│ ├── __init__.py
│ ├── test_module1.py
│ └── test_module2.py
├── docs/
│ └── documentation.md
└── myproject/
├── __init__.py
├── main.py
├── config.py
├── utils/
│ ├── __init__.py
│ ├── helpers.py
│ └── validators.py
└── models/
├── __init__.py
└── user.py

10.2 setup.py for Distribution

# setup.py
from setuptools import setup, find_packages

setup(
name="myproject",
version="1.0.0",
author="Your Name",
author_email="your.email@example.com",
description="A short description",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/yourusername/myproject",
packages=find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.8",
install_requires=[
"requests>=2.28.0",
"pandas>=1.4.0",
],
)

11. Summary

ConceptDescriptionExample
ModuleSingle Python fileimport mymodule
PackageDirectory with __init__.pyfrom package import module
importLoad moduleimport math
from...importImport specific itemsfrom math import sqrt
nameModule name variableif __name__ == "__main__":
pipPackage installerpip install requests
venvVirtual environmentpython -m venv myenv
sys.pathModule search pathsys.path.append()
Key Takeaways
  • Use modules to organize code into logical units
  • Create packages for larger projects
  • Always use virtual environments
  • Use if __name__ == "__main__": for executable scripts
  • Follow standard project structure conventions
  • Document modules with docstrings

12. What's Next?

In Module 8 - File I/O, you'll learn:

  • Reading and writing files
  • Working with different file modes
  • The with statement for file handling
  • Using pathlib for path operations
  • Working with CSV and JSON files

13. Practice Exercises

Exercise 1: Create a Math Utilities Package

Create a package with basic and advanced math operations.

math_utils/
├── __init__.py
├── basic.py
└── advanced.py

Exercise 2: Text Processing Module

Create a module with functions for text analysis (word count, character count, etc.).

# text_processor.py
def word_count(text):
# Your code here
pass

Exercise 3: Configuration Module

Create a module that reads configuration from a file and provides access to settings.

# config.py
# Your code here

Exercise 4: Logger Module

Create a custom logging module that writes to a file with timestamps.

# logger.py
# Your code here

Exercise 5: Project Structure

Set up a complete project structure with virtual environment and requirements.txt.

Solutions

Try solving these exercises on your own first. Solutions will be provided in the practice section.