Packages are collections of modules organized in directories. They let you structure larger projects hierarchically and create reusable code libraries. Understanding packages is essential for professional Python development and working with the Python ecosystem.
In this lesson, you'll learn how to create packages, use __init__.py, understand relative and absolute imports, install third-party packages with pip, and set up virtual environments. These skills are crucial for building maintainable, professional Python applications.
What You'll Learn
- Creating packages (init.py)
- Package structure and organization
- Relative vs absolute imports
- Installing third-party packages with pip
- Virtual environments (venv)
- Best practices for project structure
What is a Package?
A package is a directory containing Python modules and an __init__.py file:
my_package/
__init__.py
module1.py
module2.py
subpackage/
__init__.py
module3.py
Creating a Package
Let's create a simple package:
# my_package/__init__.py
"""My package for demonstration."""
from .module1 import function1
from .module2 import Class1
__version__ = "1.0.0"
# my_package/module1.py
def function1():
return "Function 1 from module1"
# my_package/module2.py
class Class1:
def __init__(self):
self.name = "Class1"
# Using the package
from my_package import function1, Class1
result = function1()
obj = Class1()
The init.py File
The __init__.py file makes a directory a package and can initialize it:
# my_package/__init__.py
"""Package initialization."""
# Import commonly used items for convenience
from .utils import helper_function
from .models import User, Product
# Package-level variables
VERSION = "1.0.0"
AUTHOR = "Daniel Sarney"
# Package initialization code
print("Initializing my_package...")
# my_package/utils.py
def helper_function():
return "Helper function"
# my_package/models.py
class User:
def __init__(self, name):
self.name = name
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
# Using the package
import my_package # Prints "Initializing my_package..."
from my_package import helper_function, User
Absolute vs Relative Imports
Absolute imports specify the full path from the package root:
# my_package/subpackage/module.py
from my_package.module1 import function1 # Absolute import
from my_package.subpackage.module2 import Class1 # Absolute import
Relative imports use . to indicate relative position:
# my_package/subpackage/module.py
from ..module1 import function1 # Parent package
from .module2 import Class1 # Same package
from ...other_package import something # Two levels up
Project Structure Example
Here's a well-organized project structure:
my_project/
README.md
requirements.txt
setup.py
my_package/
__init__.py
config.py
models/
__init__.py
user.py
product.py
utils/
__init__.py
helpers.py
validators.py
main.py
tests/
__init__.py
test_models.py
test_utils.py
venv/ # Virtual environment
Installing Packages with pip
pip is Python's package installer. Use it to install third-party packages:
# Install a package
pip install requests
# Install specific version
pip install requests==2.28.0
# Install from requirements file
pip install -r requirements.txt
# List installed packages
pip list
# Show package info
pip show requests
Virtual Environments
Virtual environments isolate project dependencies:
# Create virtual environment
python -m venv venv
# Activate (Windows)
venv\Scripts\activate
# Activate (macOS/Linux)
source venv/bin/activate
# Deactivate
deactivate
# Install packages in virtual environment
pip install requests
# Save dependencies
pip freeze > requirements.txt
requirements.txt
Track project dependencies:
# requirements.txt
requests==2.28.0
numpy==1.23.0
pandas==1.5.0
Install all dependencies:
pip install -r requirements.txt
Practical Package Example
Let's create a complete package:
# calculator/__init__.py
"""Calculator package."""
from .basic import add, subtract, multiply, divide
from .advanced import power, sqrt
from .scientific import sin, cos, tan
__version__ = "1.0.0"
# calculator/basic.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
# calculator/advanced.py
def power(base, exponent):
return base ** exponent
def sqrt(number):
if number < 0:
raise ValueError("Cannot calculate square root of negative number")
return number ** 0.5
# calculator/scientific.py
import math
def sin(angle):
return math.sin(math.radians(angle))
def cos(angle):
return math.cos(math.radians(angle))
def tan(angle):
return math.tan(math.radians(angle))
# Using the package
from calculator import add, power, sin
result1 = add(5, 3)
result2 = power(2, 8)
result3 = sin(30)
Setting Up a New Project
Here's a step-by-step guide:
# 1. Create project directory
mkdir my_project
cd my_project
# 2. Create virtual environment
python -m venv venv
# 3. Activate virtual environment
# Windows: venv\Scripts\activate
# macOS/Linux: source venv/bin/activate
# 4. Create package structure
mkdir my_package
touch my_package/__init__.py
touch my_package/main.py
# 5. Install dependencies
pip install requests
# 6. Create requirements.txt
pip freeze > requirements.txt
Try It Yourself
Practice creating packages:
-
Math Package: Create a
math_utilspackage with subpackages forbasic,advanced, andstatisticsoperations. -
Data Processing Package: Create a package with modules for data loading, cleaning, and analysis. Use proper
__init__.pyto expose main functions. -
Web Scraper Package: Create a package structure for a web scraper with modules for fetching, parsing, and storing data.
-
API Client Package: Create a package for an API client with separate modules for authentication, requests, and response handling.
-
Complete Project: Set up a full project with virtual environment, requirements.txt, package structure, and multiple modules.
Summary
Packages organize modules into hierarchical structures. The __init__.py file makes directories into packages and can initialize them. Absolute imports specify full paths, while relative imports use . notation. Virtual environments isolate dependencies, and requirements.txt tracks them.
Understanding packages and project structure is essential for professional Python development. Well-organized packages make code maintainable, testable, and reusable. These skills prepare you for contributing to open-source projects and building production applications.
What's Next?
In the next lesson, we'll explore working with dates and times using Python's datetime module. You'll learn how to create, format, and manipulate dates, handle timezones, and perform date arithmetic. These skills are essential for many real-world applications.