Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need "try-finally" when using @contextmanager decorator?

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?

like image 524
Kris Avatar asked Nov 07 '25 18:11

Kris


2 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

like image 89
oskros Avatar answered Nov 10 '25 08:11

oskros


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.

like image 26
ritiek Avatar answered Nov 10 '25 08:11

ritiek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!