class FileHandler:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
self.file = open(self.filename, self.mode)
print(f'Opened {self.filename}')
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
print(f'Closed {self.filename}')
if exc_type:
print(f'Exception: {exc_val}')
return False # Don't suppress exceptions
with FileHandler('test.txt', 'w') as f:
f.write('Hello!')
# Output:
# Opened test.txt
# Closed test.txtfrom contextlib import contextmanager
@contextmanager
def my_open(filename, mode):
f = open(filename, mode)
try:
print(f'Opening {filename}')
yield f # Value for 'as' variable
finally:
f.close()
print(f'Closed {filename}')
with my_open('test.txt', 'r') as f:
content = f.read()from contextlib import suppress
with suppress(FileNotFoundError):
open('nonexistent.txt', 'r')
print('This won\'t print if file missing')
print('Continued anyway!') # Always prints
# Equivalent to:
try:
open('nonexistent.txt', 'r')
except FileNotFoundError:
passimport time
class Timer:
def __enter__(self):
self.start = time.perf_counter()
return self
def __exit__(self, *args):
self.elapsed = time.perf_counter() - self.start
print(f'Elapsed: {self.elapsed:.4f}s')
with Timer() as t:
sum(range(1000000))
print(f'Stored: {t.elapsed:.4f}s')with open('in.txt') as fin, open('out.txt', 'w') as fout:
fout.write(fin.read())import sys
from contextlib import redirect_stdout
with open('output.txt', 'w') as f:
with redirect_stdout(f):
print('This goes to file, not console')Create a `Timer` class-based context manager that records start time in __enter__, calculates elapsed in __exit__, and prints the elapsed time. Create a `@contextmanager` function `temporary_file(content)` that creates a temp file with content, yields the file path, and deletes the file in finally block. Create a `DatabaseConnection` context manager that prints 'Connected' in __enter__ and 'Disconnected' in __exit__. Demonstrate all three.