Подтвердить что ты не робот

Weird Try-Except-Else-finally с операторами Return

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

Я использую 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 "****************"

Когда вы запустите этот script, он напечатает:

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

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

Почему демо возвращается 3 вместо 1? Почему демо две печати 6 вместо печати 6 Вт /4 или 5?

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

4b9b3361

Ответ 1

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

Документы Python:

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

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

Ответ 2

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

  • попробуйте блокировать все, как обычно, → finally block → завершает работу
  • попробуйте запустить блок и получить в исключение A → finally block → function end
  • try block сделать возвращаемое значение и вернуть вызов → finally block → popup return value → end end

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