简体   繁体   中英

Why is a `return` statement inside of except block silently not executed if finally block contains a return statement?

The following code prints JUST KIDDING to the console. Why does it not print " HIGH FIVE ME! "?

def f():
    print("`f` is being called")
    try:
        raise ValueError()
        raise AttributeError()
        raise type("Hell", (Exception,), dict())
    except BaseException as exc:
        print("we are in the except block")
        # WHY IS "HIGH FIVE ME!" NOT RETURNED?
        return "HIGH FIVE ME!"
    finally:
        return "JUST KIDDING"

print(f())

If that's the desired behavior, is it possible to implement something like the following pseudo-code?

If:
    finally clause, `fin` exists
        and:
    there exists except block `exc` in `fin` such that:
        there exists a return statement in `exc`
then:
    raise terrible horrible bad ugly exception

The finally is executed before exiting the try block. In fact, finally is always executed (to allow for some "clean-up" even if an error occurred). From the Python docs :

If a finally clause is present, the finally clause will execute as the last task before the try statement completes. The finally clause runs whether or not the try statement produces an exception.

In fact, even a return in try block would not get executed, try:

def f():
    print("`f` is being called")
    try:
        return "HIGH FIVE ME!"
    except BaseException as exc:
        pass
    finally:
        return "JUST KIDDING"

Just a few lines after the first quote:

If a finally clause includes a return statement, the finally clause's return statement will execute before, and instead of , the return statement in a try clause.

(My emphasis.) I guess it's safe to say the same holds for except .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM