Packages and Project Structure

Daniel Sarney
Python Intermediate

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:

  1. Math Package: Create a math_utils package with subpackages for basic, advanced, and statistics operations.

  2. Data Processing Package: Create a package with modules for data loading, cleaning, and analysis. Use proper __init__.py to expose main functions.

  3. Web Scraper Package: Create a package structure for a web scraper with modules for fetching, parsing, and storing data.

  4. API Client Package: Create a package for an API client with separate modules for authentication, requests, and response handling.

  5. 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.

Video Tutorial Coming Soon

The video tutorial for this lesson will be available soon. Check back later!

Continue Learning

12 lessons
Python For Beginners

Start your learning journey with Python For Beginners. This course includes comprehensive lessons covering everything you need to know.