Interview question
How do you write a custom context manager using __enter__ and __exit__? __enter__ और __exit__ से custom context manager कैसे लिखें?
Answer
A class becomes usable with 'with' by implementing __enter__ (setup, returns the value bound to 'as') and __exit__ (cleanup, receives exception details if one occurred).
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
print(f'Opening {self.filename}')
self.file = open(self.filename, self.mode)
return self.file # this becomes the 'as' variable
def __exit__(self, exc_type, exc_value, traceback):
print(f'Closing {self.filename}')
if self.file:
self.file.close()
if exc_type is not None:
print(f'An exception occurred: {exc_value}')
return False # False/None means exceptions propagate normally
with FileManager('test.txt', 'w') as f:
f.write('Hello World')
# Opening test.txt
# Closing test.txt
# Timing context manager - practical example
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_value, traceback):
elapsed = time.time() - self.start
print(f'Elapsed: {elapsed:.4f}s')
with Timer():
total = sum(range(1000000))
# Elapsed: 0.0234s (example)
# Database connection pattern - very common real-world use
class DatabaseConnection:
def __enter__(self):
print('Connecting to database')
self.conn = 'connection_object'
return self.conn
def __exit__(self, exc_type, exc_value, traceback):
print('Closing database connection')
# cleanup happens regardless of success or failureClass को 'with' के साथ इस्तेमाल करने योग्य बनाने के लिए __enter__ (setup, 'as' variable return करता है) और __exit__ (cleanup, exception details मिलते हैं) implement करने होते हैं।
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
print(f'Opening {self.filename}')
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, traceback):
print(f'Closing {self.filename}')
if self.file:
self.file.close()
if exc_type is not None:
print(f'Exception आया: {exc_value}')
return False
with FileManager('test.txt', 'w') as f:
f.write('Hello World')
# Timing context manager
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_value, traceback):
elapsed = time.time() - self.start
print(f'Elapsed: {elapsed:.4f}s')
with Timer():
total = sum(range(1000000))Was this answer clear?