Странное поведение Try-Except-Else-Finally с инструкциями Return [дубликат]


этот вопрос уже есть ответ здесь:

  • возвращение ест исключение 4 ответы

Это какой-то код, который ведет себя странно. Это упрощенная версия поведения, которое я написал. Это все равно продемонстрирует странное поведение, и у меня были некоторые конкретные вопросы о том, почему это происходит.

Я использую Python 2.6.6 на Windows 7.

def demo1():
    try:
        raise RuntimeError,"To Force Issue"
    except:
        return 1
    else:
        return 2
    finally:
        return 3

def demo2():
    try:
        try:
            raise RuntimeError,"To Force Issue"
        except:
            return 1
        else:
            return 2
        finally:
            return 3
    except:
        print 4
    else:
        print 5
    finally:
        print 6

if __name__ == "__main__":
    print "*** DEMO ONE ***"
    print demo1()
    print "****************"
    print 
    print "*** DEMO TWO ***"
    print demo2()
    print "****************"

при запуске этого скрипта, он будет печатать:

*** DEMO ONE ***
3
****************

*** DEMO TWO ***
6
3
****************

почему demo one возвращает 3 вместо 1? Почему demo two печатает 6 вместо печати 6 w / 4 или 5?

Спасибо за вашу помощь.

2 55

2 ответа:

, потому что finally отчетность гарантированный для выполнения (ну, предполагая отсутствие отключения электроэнергии или что-либо вне контроля Python). Это означает, что прежде чем функция сможет вернуться, она должна запустить блок finally, который возвращает другое значение.

The Python docs состояние:

когда оператор return, break или continue выполняется в наборе try try...наконец, заявление, finally пункт тоже выполнен на выход."Заявление о продолжении является незаконным в пункте finally. (Причина-проблемы с текущей реализацией - это ограничение может быть снято в будущем).

Это означает, что при попытке возврата,finally блок вызывается, возвращая его значение, а не тот, который у вас был бы.

порядок выполнения:

  1. попробуйте блок все завершается нормально - > наконец блок - > функция заканчивается
  2. попробуйте запустить блок и попасть в исключение A - > наконец блок - > функция заканчивается
  3. блок try сделать возврат стоимости и звонить вернуть -> блок finally -> всплывающее окно, возвращаемое значение -> функция заканчивается

таким образом, любое возвращение в блоке finally завершит шаги заранее.