Why do we need "try-finally" when using @contextmanager decorator?
Question:
I wonder why we need to use a try-finally when using a the @contextmanager decorator.
The provided example suggests:
from contextlib import contextmanager
@contextmanager
def managed_resource(*args, **kwds):
resource = acquire_resource(*args, **kwds)
try:
yield resource
finally:
release_resource(resource)
It seems to me, however, that this will do the exact same thing:
@contextmanager
def managed_resource(*args, **kwds):
resource = acquire_resource(*args, **kwds)
yield resource
release_resource(resource)
I’m sure I must be missing something. What am I missing?
Answers:
Because a finally
statement is guaranteed to run no matter what (except a power outage), before the code can terminate. So writing it like this guarantees that the resource is always released
finally
makes sure that the code under it is always executed even if there’s an exception raised:
from contextlib import contextmanager
@contextmanager
def exception_handler():
try:
yield
finally:
print("cleaning up")
with exception_handler():
result = 10 / 0
If there were no try-finally, the above example wouldn’t cleanup itself afterwards.
I wonder why we need to use a try-finally when using a the @contextmanager decorator.
The provided example suggests:
from contextlib import contextmanager
@contextmanager
def managed_resource(*args, **kwds):
resource = acquire_resource(*args, **kwds)
try:
yield resource
finally:
release_resource(resource)
It seems to me, however, that this will do the exact same thing:
@contextmanager
def managed_resource(*args, **kwds):
resource = acquire_resource(*args, **kwds)
yield resource
release_resource(resource)
I’m sure I must be missing something. What am I missing?
Because a finally
statement is guaranteed to run no matter what (except a power outage), before the code can terminate. So writing it like this guarantees that the resource is always released
finally
makes sure that the code under it is always executed even if there’s an exception raised:
from contextlib import contextmanager
@contextmanager
def exception_handler():
try:
yield
finally:
print("cleaning up")
with exception_handler():
result = 10 / 0
If there were no try-finally, the above example wouldn’t cleanup itself afterwards.