Unit 5 • Lesson 5

Working with Packages

Overview

Packages are collections of related modules organized in folders. You'll learn how to create packages with __init__.py files and how they help manage large-scale Python applications with many interconnected files, enabling better project organization.

Intermediate 20–25 min

What You Will Learn in This Lesson

By the end of this lesson, you will know:

  • What packages are: Understand that packages are folders containing multiple modules.
  • Creating packages: Learn how to create packages using __init__.py files.
  • Importing from packages: Discover how to import modules from package directories.
  • Package structure: Understand how to organize code into logical package hierarchies.

Why This Matters

As your projects grow, you'll have many modules. Instead of putting them all in one folder, packages let you organize them into logical folders. Think of packages like chapters in a book - each chapter (package) contains related pages (modules). This makes large projects much easier to navigate and maintain!

Step 1: What Is a Package?

A package is a folder that contains Python modules. To make a folder a package, you need to add an __init__.py file (which can be empty). This tells Python that the folder should be treated as a package:

Package Structure
myproject/
    ├── main.py
    └── utils/
        ├── __init__.py    # Makes utils a package
        ├── math_utils.py
        └── string_utils.py
1

Folder Structure

Packages are folders containing one or more Python modules. The folder name becomes the package name.

2

__init__.py File

The __init__.py file (even if empty) tells Python that the folder is a package. Without it, Python won't recognize the folder as a package.

3

Module Files

Inside the package folder, you place your module files (Python files). These modules belong to the package.

Key Concept: A package is like a folder organizer. Instead of having all your files in one messy folder, packages let you organize related modules into separate folders. The __init__.py file tells Python "this folder is a package, treat it specially!"

Mini Practice #1: Understanding Package Structure

Try It Yourself

In a real project, you would create a folder structure. For this practice, we'll simulate importing from a package:

Press Run to see output

What happened? In a real project, these functions would be in utils/math_utils.py, and you could import them using from utils.math_utils import add. Packages organize related modules together, making it easier to find and use code!

Step 2: Creating a Package

To create a package, follow these steps:

Creating a Package
# 1. Create a folder (e.g., "utils")
# 2. Create __init__.py file inside the folder
# 3. Add your module files

# utils/__init__.py (can be empty or contain package initialization)
# utils/math_utils.py
def add(a, b):
    return a + b

# utils/string_utils.py
def greet(name):
    return f"Hello, {name}!"
1

Create Folder

Create a folder with a descriptive name. This becomes your package name (e.g., utils, models, controllers).

2

Add __init__.py

Create an empty file called __init__.py inside the folder. This file can be empty or contain package initialization code.

3

Add Modules

Place your Python module files inside the package folder. These modules are now part of the package.

__init__.py Purpose

The __init__.py file serves two purposes:

  1. It marks the folder as a Python package (required for Python to recognize it)
  2. It can contain initialization code that runs when the package is imported

In Python 3.3+, __init__.py can be empty, but it's still good practice to include it for clarity!

Step 3: Importing from Packages

You can import modules from packages using dot notation:

Importing from Packages
# Import entire module from package
from utils import math_utils
result = math_utils.add(5, 3)

# Import specific function
from utils.math_utils import add
result = add(5, 3)

# Import entire package (if __init__.py exports modules)
import utils
result = utils.math_utils.add(5, 3)
1

From Package Import Module

from utils import math_utils imports the math_utils module from the utils package.

2

From Package Import Function

from utils.math_utils import add imports the add function directly from the module in the package.

3

Dot Notation

Use dots to specify the package path: package.module.function. This tells Python exactly where to find what you need!

Mini Practice #2: Package Organization

Try It Yourself

Simulate organizing code into packages:

Press Run to see output

What happened? In a real project, these functions would be in utils/math_utils.py, and you'd import them with from utils.math_utils import add, multiply. Packages let you organize code logically - all math-related functions go in the math_utils module, which is in the utils package!

Step 4: Nested Packages

Packages can contain other packages, creating a hierarchy:

Nested Package Structure
myproject/
    ├── main.py
    └── utils/
        ├── __init__.py
        ├── math/
        │   ├── __init__.py
        │   └── basic.py
        └── string/
            ├── __init__.py
            └── formatting.py

# Import from nested package
from utils.math import basic
from utils.string.formatting import capitalize

Best Practices

  • Keep package names short and descriptive
  • Group related modules together in the same package
  • Use nested packages for very large projects
  • Always include __init__.py files (even if empty)

End-of-Lesson Exercises

Exercise 1: Simulate Package Structure

Create functions greet(name) and farewell(name) that return greeting messages. Simulate importing them from a package called greetings and use them to greet "Python" and say farewell to "Python". Print both results.

Define the functions, then call them with "Python".

Write your code above and click "Check Answer" to verify it's correct.

Exercise 2: Organize Functions

Create a function square(n) that returns n ** 2, and a function cube(n) that returns n ** 3. Simulate organizing them into a package. Calculate and print square(5) and cube(3).

Define both functions, then call them with the specified values.

Write your code above and click "Check Answer" to verify it's correct.