Почему оператор `return` внутри блока кроме молча не выполняется, если блок finally содержит оператор возврата? - PullRequest
0 голосов
/ 25 октября 2019

Следующий код выводит JUST KIDDING на консоль. Почему не печатается "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:
    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

1 Ответ

1 голос
/ 25 октября 2019

finally выполняется перед выходом из блока try. Фактически, finally всегда выполняется (чтобы обеспечить некоторую «очистку», даже если произошла ошибка). Из документов Python :

Если присутствует предложение finally, предложение finally будет выполнено как последняя задача перед завершением оператора try. Предложение finally запускается независимо от того, выдает ли оператор try исключение.

Фактически, даже блок return в try не будет выполнен, попробуйте:

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

Всего через несколько строк после первой кавычки:

Если предложение finally содержит оператор return, оператор finally предложения *1025* будет выполняться раньше, и вместо оператор return в предложении try.

(мой акцент.) Я думаю, можно с уверенностью сказать, что то же самое верно для except.

...