Skip to content

Python Context Managers

This guide covers Python context managers, their implementation, and common use cases.

Table of Contents

Introduction

What are Context Managers?

Context managers are objects that implement the context manager protocol, providing a way to manage resources and handle setup and cleanup operations automatically.

Key Concepts

  • Resource management
  • Automatic cleanup
  • Exception handling
  • Context protocol

Basic Usage

File Operations

1
2
3
4
5
6
7
# Reading a file
with open('data.txt', 'r') as file:
    content = file.read()

# Writing to a file
with open('output.txt', 'w') as file:
    file.write('Hello, World!')

Reading Files in Chunks

1
2
3
with open('large_file.txt', 'r') as file:
    while (chunk := file.read(10000)):
        process_chunk(chunk)

Database Connections

1
2
3
4
5
6
import sqlite3

with sqlite3.connect('database.db') as conn:
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM users')
    results = cursor.fetchall()

Custom Context Managers

Class-based Implementation

class ListTransaction:
    def __init__(self, thelist):
        self.thelist = thelist
        self.workingcopy = None

    def __enter__(self):
        self.workingcopy = list(self.thelist)
        return self.workingcopy

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is None:
            self.thelist[:] = self.workingcopy
        return False

Function-based Implementation

1
2
3
4
5
6
7
8
9
from contextlib import contextmanager

@contextmanager
def managed_resource():
    print("Setting up resource")
    try:
        yield "resource"
    finally:
        print("Cleaning up resource")

Error Handling

class ErrorHandler:
    def __init__(self, error_types):
        self.error_types = error_types

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type in self.error_types:
            print(f"Handled {exc_type.__name__}")
            return True
        return False

Common Patterns

Resource Management

class ResourceManager:
    def __init__(self, resource):
        self.resource = resource

    def __enter__(self):
        self.resource.acquire()
        return self.resource

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.resource.release()

Timing Operations

import time

class Timer:
    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time.time()
        self.duration = self.end - self.start

Directory Management

import os
import shutil

class TemporaryDirectory:
    def __init__(self, dirname):
        self.dirname = dirname

    def __enter__(self):
        os.makedirs(self.dirname, exist_ok=True)
        return self.dirname

    def __exit__(self, exc_type, exc_val, exc_tb):
        shutil.rmtree(self.dirname)

Best Practices

  1. Resource Management
  2. Always clean up resources
  3. Handle exceptions properly
  4. Use appropriate context managers

  5. Error Handling

  6. Implement proper error handling
  7. Return appropriate values from exit
  8. Document error behavior

  9. Performance

  10. Minimize setup/teardown overhead
  11. Use appropriate resource management
  12. Consider context manager scope

  13. Code Organization

  14. Keep context managers focused
  15. Use clear and descriptive names
  16. Document behavior clearly

  17. Decorators

  18. Error Handling
  19. Resource Management
  20. Performance Optimization