Return 문을 사용한 이상한 Try-Except-Else-Finally 동작


88

이것은 특이하게 작동하는 코드입니다. 이것은 내가 작성한 동작의 단순화 된 버전입니다. 이것은 여전히 ​​이상한 행동을 보여줄 것이며 왜 이것이 발생하는지에 대한 몇 가지 구체적인 질문이있었습니다.

Windows 7에서 Python 2.6.6을 사용하고 있습니다.

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

결과 :

>>> print demo1()
3
>>> print demo2()
6
3
  • 데모 1이 1 대신 3을 반환하는 이유는 무엇입니까?
  • 데모 2가 6을 4 또는 5로 인쇄하는 대신 6으로 인쇄하는 이유는 무엇입니까?

답변:


124

때문에 finally문이되어 보장 실행되는 (물론, 파이썬의 제어 전원이 정전 또는 아무것도의 외부 염치 없음). 즉, 함수가 반환되기 전에 다른 값을 반환하는 finally 블록을 실행해야합니다.

파이썬 문서의 상태 :

try… finally 문의 try 스위트에서 return, break 또는 continue 문이 실행되면 finally 절도 '출구 도중'실행됩니다.

함수의 반환 값은 마지막으로 실행 된 return 문에 의해 결정됩니다. finally 절은 항상 실행되기 때문에 finally 절에서 실행 된 return 문은 항상 마지막으로 실행 된 문이됩니다.

이것은 당신이 반환하려고 할 때 finally블록이 호출되어 당신이 가지고 있었을 값이 아닌 그 값 을 반환한다는 것을 의미합니다 .


4
두 번째 예에서 5가 인쇄되지 않는 이유는 무엇입니까? 이것은 아직 잘 설명되지 않은 것 같습니다. 반환 하나 잘 대답하지만 왜 두 번째 예제 인쇄에 5 나던있다
Joran 비즐리를

5
아, 나는 마침내 외부에 즉시 뛰어 원인 초기 시도에 반환에서 그것을 생각 생각
Joran 비즐리를

2
finally블록이 항상 실행 되기 때문 입니다.
Gareth Latty

2
데모 2에서는 왜 최종적으로 중첩을 실행하고 외부로 킥 아웃 한 다음 최종적으로 외부에서 None을 반환하는 대신 반환을 완료하기 위해 최종적으로 중첩으로 돌아가는 이유는 무엇입니까?
Kyle Owens

1
return명령문이 호출 될 때 Python은 finally실행해야하는 열린 절을 확인 하기 때문입니다 (위의 인용문 참조).
Gareth Latty

6

실행 순서는 다음과 같습니다.

  1. 모든 시도 차단 정상적으로 완료-> 최종 차단-> 기능 종료
  2. 블록 실행을 시도하고 예외 A에 들어가십시오-> 마지막으로 블록-> 기능 종료
  3. try 블록은 반환 값을 만들고 return 호출-> finally 블록-> 팝업 반환 값-> 함수 종료

따라서 finally 블록의 모든 반환은 사전에 단계를 종료합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.