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?