Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Question 6 of 10 · Exception Handling & Debugging
Interview question

How do context managers (the 'with' statement) relate to exception handling? Context managers ('with' statement) exception handling से कैसे संबंधित हैं?

Answer

The 'with' statement guarantees cleanup code runs even if an exception occurs inside the block, using a context manager's __enter__ and __exit__ methods - similar in spirit to finally, but reusable and cleaner.

# Without 'with' - manual cleanup, easy to forget on exceptions
f = open('file.txt')
try:
    data = f.read()
    result = 10 / 0  # exception occurs
finally:
    f.close()  # must remember this every time

# With 'with' - cleanup guaranteed automatically
with open('file.txt') as f:
    data = f.read()
    result = 10 / 0  # exception occurs
    # f.close() is called automatically even though the exception interrupted execution

# Custom context manager showing exception handling in __exit__
class Resource:
    def __enter__(self):
        print('Acquiring resource')
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print('Releasing resource')
        if exc_type is ValueError:
            print(f'Suppressing ValueError: {exc_value}')
            return True  # returning True suppresses the exception
        return False  # returning False/None lets the exception propagate

with Resource() as r:
    raise ValueError('Something went wrong')
print('Execution continues here') # reached because __exit__ suppressed it

# contextlib makes writing context managers easier with a generator
from contextlib import contextmanager

@contextmanager
def managed_resource():
    print('Setup')
    try:
        yield 'resource'
    finally:
        print('Teardown')  # always runs, exception or not

with managed_resource() as r:
    print(f'Using {r}')

'with' statement यह guarantee करता है कि block के अंदर exception आने पर भी cleanup code चले, context manager के __enter__ और __exit__ methods इस्तेमाल करके - finally जैसा पर reusable और cleaner।

# 'with' के बिना - manual cleanup, भूलना आसान
f = open('file.txt')
try:
    data = f.read()
    result = 10 / 0
finally:
    f.close()

# 'with' के साथ - cleanup automatic
with open('file.txt') as f:
    data = f.read()
    result = 10 / 0
    # f.close() automatically call होता है

# Custom context manager
class Resource:
    def __enter__(self):
        print('Resource acquire')
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print('Resource release')
        if exc_type is ValueError:
            print(f'ValueError suppress: {exc_value}')
            return True  # exception suppress हो जाता है
        return False

with Resource() as r:
    raise ValueError('कुछ गलत हुआ')
print('यहां execution जारी रहता है')

# contextlib generator से आसान बनाता है
from contextlib import contextmanager

@contextmanager
def managed_resource():
    print('Setup')
    try:
        yield 'resource'
    finally:
        print('Teardown')

with managed_resource() as r:
    print(f'Using {r}')

Was this answer clear?