Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Question 4 of 10 · Django Signals & Decorators
Interview question

How do you use context managers and context decorators (@contextmanager) in Python? Python में context managers और @contextmanager decorators कैसे use करते हैं?

Answer

Context managers handle resource allocation and cleanup (files, database connections). They use `__enter__` and `__exit__` methods or @contextmanager decorator for cleaner syntax.

// Context Manager - Class Based
class DatabaseConnection:
    def __enter__(self):
        print("Opening database connection")
        self.db = connect_to_db()
        return self.db
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Closing database connection")
        self.db.close()
        return False  # Don't suppress exceptions

// Usage with 'with' statement
with DatabaseConnection() as db:
    result = db.query("SELECT * FROM books")
    print(result)
# Connection automatically closed

// Context Manager Decorator (@contextmanager)
from contextlib import contextmanager

@contextmanager
def database_connection():
    db = connect_to_db()
    try:
        yield db
    finally:
        db.close()

// Usage
with database_connection() as db:
    result = db.query("SELECT * FROM books")

// Practical Example - File Handling
# Python handles this automatically
with open("file.txt", "r") as f:
    content = f.read()
# File closed automatically

// Custom Context Manager - Transaction
from contextlib import contextmanager

@contextmanager
def atomic_transaction(db):
    try:
        db.begin()
        yield db
        db.commit()
    except Exception as e:
        db.rollback()
        raise

// Usage
with atomic_transaction(db) as txn:
    txn.execute("UPDATE books SET price = 100")
    txn.execute("UPDATE inventory SET count = 50")

// Django's Context Manager
from django.db import transaction

with transaction.atomic():
    book = Book.objects.create(title="New Book")
    review = Review.objects.create(book=book, rating=5)
    # Both operations atomic - rollback if either fails

// Suppress Exceptions
from contextlib import suppress

with suppress(FileNotFoundError):
    os.remove("file.txt")  # Won't raise if file doesn't exist

// Redirect Context
from contextlib import redirect_stdout
import io

output = io.StringIO()
with redirect_stdout(output):
    print("Hello World")

result = output.getvalue()  # "Hello World\
"

Context managers resource allocation और cleanup handle करते हैं। `with` statement के साथ use होते हैं।

// Class-based context manager
class DatabaseConnection:
    def __enter__(self):
        print("Connection opening")
        self.db = connect()
        return self.db
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Connection closing")
        self.db.close()

with DatabaseConnection() as db:
    result = db.query()

// @contextmanager decorator
from contextlib import contextmanager

@contextmanager
def db_connection():
    db = connect()
    try:
        yield db
    finally:
        db.close()

with db_connection() as db:
    result = db.query()

Was this answer clear?