This tutorial will guide you through creating Python modules and packages, organizing your code into reusable components, and distributing them effectively. You’ll learn how to structure your code, import modules, and create packages for real-world applications.

Beginner30 minutes

Step 1: Understanding Python Modules

A Python module is a single file containing Python code (functions, classes, or variables) that can be reused in other programs. Modules help organize code and make it more maintainable.

- Key Concepts:

- A module is a .py file.

- Use the import statement to include a module in your program.

- Modules can be standard (built-in) or custom (created by you).

# Example: Creating a simple module
# Save this as `math_operations.py`
def add(a, b):
    return a + b

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

Practice Exercise

Create a module named string_utils.py that contains two functions: reverse_string(s) to reverse a string and count_vowels(s) to count the number of vowels in a string. Then, write a script to import and use these functions.

Show Solution
# string_utils.py
def reverse_string(s):
    return s[::-1]

def count_vowels(s):
    vowels = 'aeiouAEIOU'
    return sum(1 for char in s if char in vowels)

# main.py
import string_utils

print(string_utils.reverse_string('hello'))  # Output: 'olleh'
print(string_utils.count_vowels('hello'))   # Output: 2

Step 2: Importing Modules

Once you've created a module, you can import it into other scripts using the import statement. You can also import specific functions or variables using from ... import ....

- Key Concepts:

- Use import module_name to import the entire module.

- Use from module_name import function_name to import specific functions.

- Use import module_name as alias to create an alias for the module.

# Importing the math_operations module
import math_operations

result = math_operations.add(5, 3)
print(result)  # Output: 8

Practice Exercise

Create a script that imports the string_utils module from the previous exercise. Use both functions (reverse_string and count_vowels) to process the string 'Python is awesome!'.

Show Solution
# main.py
import string_utils

s = 'Python is awesome!'
print(string_utils.reverse_string(s))  # Output: '!emosewa si nohtyP'
print(string_utils.count_vowels(s))   # Output: 6

Step 3: Creating Python Packages

A Python package is a collection of modules organized in a directory. Packages allow you to group related modules together and provide a hierarchical structure for your code.

- Key Concepts:

- A package is a directory containing an __init__.py file.

- The __init__.py file can be empty or contain initialization code.

- Use dot notation to import modules from a package (e.g., package_name.module_name).

# Example: Creating a package
# Directory structure:
# my_package/
#   __init__.py
#   math_operations.py
#   string_utils.py

# __init__.py (can be empty)

# Importing from the package
from my_package import math_operations

result = math_operations.subtract(10, 4)
print(result)  # Output: 6

Practice Exercise

Create a package named data_processing with two modules: data_cleaning.py (contains a function remove_duplicates(data) to remove duplicates from a list) and data_analysis.py (contains a function calculate_mean(data) to calculate the mean of a list). Write a script to import and use these functions.

Show Solution
# data_processing/data_cleaning.py
def remove_duplicates(data):
    return list(set(data))

# data_processing/data_analysis.py
def calculate_mean(data):
    return sum(data) / len(data)

# main.py
from data_processing import data_cleaning, data_analysis

data = [1, 2, 2, 3, 4, 4, 5]
cleaned_data = data_cleaning.remove_duplicates(data)
mean = data_analysis.calculate_mean(cleaned_data)
print(cleaned_data)  # Output: [1, 2, 3, 4, 5]
print(mean)          # Output: 3.0

Step 4: Using `__init__.py` for Package Initialization

The __init__.py file is executed when a package is imported. It can be used to initialize package-level variables, import submodules, or define what gets imported when using from package import *.

- Key Concepts:

- Use __init__.py to control package behavior.

- Define __all__ to specify which modules are imported with from package import *.

# Example: Using __init__.py
# my_package/__init__.py
__all__ = ['math_operations', 'string_utils']

# Importing all modules from the package
from my_package import *

result = math_operations.add(7, 3)
print(result)  # Output: 10

Practice Exercise

Modify the data_processing package's __init__.py file to include __all__ and import the remove_duplicates and calculate_mean functions directly when using from data_processing import *. Test this in a script.

Show Solution
# data_processing/__init__.py
__all__ = ['data_cleaning', 'data_analysis']
from .data_cleaning import remove_duplicates
from .data_analysis import calculate_mean

# main.py
from data_processing import *

data = [1, 2, 2, 3, 4, 4, 5]
cleaned_data = remove_duplicates(data)
mean = calculate_mean(cleaned_data)
print(cleaned_data)  # Output: [1, 2, 3, 4, 5]
print(mean)          # Output: 3.0

Step 5: Distributing Packages with `setuptools`

To share your packages with others, you can use setuptools to create a distributable package. This involves creating a setup.py file and specifying package metadata.

- Key Concepts:

- Use setuptools.setup() to define package details.

- Include dependencies in install_requires.

- Use python setup.py sdist bdist_wheel to build the package.

# Example: setup.py
from setuptools import setup, find_packages

setup(
    name='data_processing',
    version='0.1',
    packages=find_packages(),
    install_requires=[],
    description='A package for data processing tasks.',
    author='Your Name',
    author_email='your.email@example.com'
)

Practice Exercise

Create a setup.py file for the data_processing package. Add a dependency for numpy in install_requires. Build the package using python setup.py sdist bdist_wheel.

Show Solution
# setup.py
from setuptools import setup, find_packages

setup(
    name='data_processing',
    version='0.1',
    packages=find_packages(),
    install_requires=['numpy'],
    description='A package for data processing tasks.',
    author='Your Name',
    author_email='your.email@example.com'
)

# Run in terminal:
# python setup.py sdist bdist_wheel

Step 6: Testing and Debugging Modules and Packages

Testing is crucial to ensure your modules and packages work as expected. Use Python's unittest or pytest framework to write tests.

- Key Concepts:

- Write test cases for each function.

- Use assert statements to check expected outcomes.

- Run tests using python -m unittest or pytest.

# Example: Writing a test for math_operations.py
import unittest
from my_package.math_operations import add, subtract

class TestMathOperations(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(2, 3), 5)

    def test_subtract(self):
        self.assertEqual(subtract(5, 3), 2)

if __name__ == '__main__':
    unittest.main()

Practice Exercise

Write a test suite for the data_processing package. Test both remove_duplicates and calculate_mean functions using unittest. Include edge cases like empty lists or lists with a single element.

Show Solution
# test_data_processing.py
import unittest
from data_processing.data_cleaning import remove_duplicates
from data_processing.data_analysis import calculate_mean

class TestDataProcessing(unittest.TestCase):
    def test_remove_duplicates(self):
        self.assertEqual(remove_duplicates([1, 2, 2, 3]), [1, 2, 3])
        self.assertEqual(remove_duplicates([]), [])

    def test_calculate_mean(self):
        self.assertEqual(calculate_mean([1, 2, 3]), 2)
        self.assertEqual(calculate_mean([5]), 5)
        with self.assertRaises(ZeroDivisionError):
            calculate_mean([])

if __name__ == '__main__':
    unittest.main()

Step 7: Documenting Your Modules and Packages

Good documentation helps others understand and use your code. Use docstrings to describe modules, functions, and classes. You can also generate documentation using tools like Sphinx.

- Key Concepts:

- Use triple quotes (""") for docstrings.

- Follow the Google or NumPy docstring format.

- Use help() or .__doc__ to view docstrings.

# Example: Adding docstrings to math_operations.py
"""
math_operations.py
A module for basic math operations.
"""

def add(a, b):
    """
    Add two numbers.

    Args:
        a (int or float): The first number.
        b (int or float): The second number.

    Returns:
        int or float: The sum of a and b.
    """
    return a + b

Practice Exercise

Add docstrings to all functions in the data_processing package. Use the Google docstring format. Then, use the help() function to view the documentation for remove_duplicates and calculate_mean.

Show Solution
# data_processing/data_cleaning.py
"""
data_cleaning.py
A module for cleaning data.
"""

def remove_duplicates(data):
    """
    Remove duplicates from a list.

    Args:
        data (list): The input list.

    Returns:
        list: A list with duplicates removed.
    """
    return list(set(data))

# data_processing/data_analysis.py
"""
data_analysis.py
A module for analyzing data.
"""

def calculate_mean(data):
    """
    Calculate the mean of a list.

    Args:
        data (list): The input list.

    Returns:
        float: The mean of the list.

    Raises:
        ZeroDivisionError: If the list is empty.
    """
    return sum(data) / len(data)

# Viewing documentation
help(remove_duplicates)
help(calculate_mean)

Sign in to take Cornell notes on this lesson — they save automatically and stay with your account.

Sign in

Click to access the login or register cheese