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?
CodePudding user response:
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
CodePudding user response:
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.