Modules & Packages

Organizing your code and using external functionality

Introduction

As your programs grow, keeping all your code in a single file becomes unmanageable. Python lets you break code into modules (reusable files) that can be imported and used in other programs. In this lesson, you'll learn how to import standard modules, create your own, and utilize packages.

What is a Module?

A module is any Python file (ending in .py) that can contain variables, functions, classes, and runnable code. Modules help you organize code by grouping related objects and functions together.

# greetings.py
def say_hello(name):
    print(f"Hello, {name}!")

Importing Modules

Use the import statement to use code from other modules, both standard library and your own files.

# Importing a module
import math
print(math.sqrt(16))   # 4.0

# Importing specific items
from math import pi, sin
print(pi)              # 3.1415...
print(sin(0))          # 0.0

# Importing your own module
import greetings
greetings.say_hello("Alice")

Aliasing & Import Variants

# Use 'as' to create an alias
import numpy as np
import pandas as pd

# Wildcard (not recommended)
from math import *

# Now sqrt(), pi, etc are available without math.
Warning: Avoid from module import * in real projects; it pollutes your namespace and makes code harder to understand. But: There are niche cases, like plugin or component registration patterns, where wildcard imports can be useful for auto-discovering components.

Note: Third-party packages like numpy and pandas must be installed first using pip install numpy pandas before you can import them. Standard library modules (like math, random) work out of the box.

Creating Your Own Modules

# In file: calculator.py
def add(a, b):
    return a + b

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

# In another file:
import calculator

print(calculator.add(3, 4))   # 7
print(calculator.subtract(10, 5))  # 5
Tip: Place your reusable code (utility functions, constants) into modules to keep your main scripts clean and organized.

Packages (Directories of Modules)

A package is a folder containing an __init__.py file and any number of modules. Import packages using dot notation.

Basic Package Structure

# Directory structure:
# mypackage/
#   __init__.py
#   helpers.py
#   math_utils.py

from mypackage import helpers
from mypackage.math_utils import square

# Or import everything:
import mypackage

What Goes in __init__.py?

The __init__.py file can be empty (it just marks the directory as a package), or it can contain initialization code and convenient imports.

# mypackage/__init__.py
"""
This file makes the directory a Python package.
Can be empty, or can contain initialization code.
"""

# Import commonly used items for convenience
from .helpers import format_name, clean_text
from .math_utils import square, cube

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

# Now users can do:
# from mypackage import square
# Instead of:
# from mypackage.math_utils import square

Best Practice: Use __init__.py to expose commonly used functions at the package level. This makes your package easier to use and hides internal organization from users.

The if __name__ == "__main__" Pattern

This special pattern allows you to write modules that can be both imported (as a library) and executed (as a script). It's one of the most important patterns in Python module design.

How It Works

# calculator.py
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

# This code only runs when script is executed directly
if __name__ == "__main__":
    # Test/demo code
    print("Testing calculator module...")
    print(f"5 + 3 = {add(5, 3)}")      # 8
    print(f"10 - 4 = {subtract(10, 4)}")  # 6
    print(f"7 * 6 = {multiply(7, 6)}")    # 42
    print("All tests passed!")

When you run this file directly (python calculator.py), __name__ is set to "__main__", so the test code executes. When you import it (import calculator), __name__ is set to "calculator", so the test code is skipped.

Practical Example

# data_processor.py
def clean_data(data):
    """Remove empty strings and strip whitespace"""
    return [item.strip() for item in data if item.strip()]

def calculate_average(numbers):
    """Calculate average of numbers"""
    if not numbers:
        return 0
    return sum(numbers) / len(numbers)

if __name__ == "__main__":
    # Demo: shows how to use the module
    sample_data = ["  hello  ", "", "  world  ", "   "]
    cleaned = clean_data(sample_data)
    print(f"Cleaned data: {cleaned}")
    # Cleaned data: ["hello", "world"]

    scores = [85, 92, 78, 95, 88]
    avg = calculate_average(scores)
    print(f"Average score: {avg}")
    # Average score: 87.6

When to use this pattern:

  • Adding test/demo code to modules
  • Creating command-line tools (scripts that can also be imported)
  • Running examples when module is executed directly
  • Debugging/development testing

Using the Standard Library

Python comes with a rich standard library - a collection of modules that are always available without installation. Here are some commonly used examples:

math

Mathematical functions and constants

import math

# Common functions
print(math.sqrt(36))    # 6.0
print(math.pi)          # 3.14159...
print(math.ceil(4.2))   # 5
print(math.floor(4.8))  # 4
random

Random number generation and choices

import random

# Random numbers
print(random.randint(1, 100))  # 1-100
print(random.random())  # 0.0-1.0

# Random choice
colors = ["red", "blue", "green"]
print(random.choice(colors))

Want to learn more? The standard library includes many powerful modules for common tasks:

  • datetime - Working with dates and times
  • json - Reading and writing JSON data
  • collections - Advanced data structures (Counter, defaultdict)
  • os and pathlib - File system operations

These are covered in detail in Lesson 12: Standard Library Essentials.

Key Takeaways

Modules

  • Break code into reusable .py files
  • Import with import or from ... import ...
  • Use if __name__ == "__main__" for script/module duality
  • Create your own modules for organization

Packages

  • Folder with __init__.py file
  • Use dot notation for importing
  • __init__.py can expose convenient imports
  • Group related modules together

Third-Party Packages

  • Use pip install package_name
  • Standard library modules work out of the box
  • Popular packages: numpy, pandas, requests

Best Practices

  • Use aliases for long names (import numpy as np)
  • Avoid from module import *
  • See Lesson 12 for standard library deep dive
What's Next?

You're now ready to organize your code and use powerful external libraries! In the next lessons, we'll explore:

  • String manipulation & formatting - Master string operations, slicing, and modern formatting techniques
  • List comprehensions & lambda - Write cleaner, more Pythonic code with elegant one-liners
  • Standard library essentials - Leverage datetime, json, collections, and os modules
  • Debugging techniques - Learn to find and fix bugs like a professional developer