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.