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.
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__.pyfiles. - 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:
myproject/
├── main.py
└── utils/
├── __init__.py # Makes utils a package
├── math_utils.py
└── string_utils.py
Folder Structure
Packages are folders containing one or more Python modules. The folder name becomes the package name.
__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.
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 YourselfIn a real project, you would create a folder structure. For this practice, we'll simulate importing from a package:
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:
# 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}!"
Create Folder
Create a folder with a descriptive name. This becomes your package name (e.g., utils, models, controllers).
Add __init__.py
Create an empty file called __init__.py inside the folder. This file can be empty or contain package initialization code.
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:
- It marks the folder as a Python package (required for Python to recognize it)
- 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:
# 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)
From Package Import Module
from utils import math_utils imports the math_utils module from the utils package.
From Package Import Function
from utils.math_utils import add imports the add function directly from the module in the package.
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 YourselfSimulate organizing code into packages:
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:
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__.pyfiles (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".
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.