Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 3110 – Python 3000에서 예외 잡기

Author:
Collin Winter <collinwinter at google.com>
Status:
Final
Type:
Standards Track
Created:
16-Jan-2006
Python-Version:
3.0
Post-History:


Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

이 PEP는 Python의 문법에서 모호성을 제거하고, 예외 클래스를 단순화하며, 예외의 가비지 컬렉션을 간소화하고, Python 3.0에서 언어의 크기를 줄이는 데 도움이 되도록 의도된 변경 사항을 도입합니다.

근거

  1. Python 2.x의 except 절은 파서가 다음 두 경우 중 어느 것인지 구별할 수 없는 구문적 모호성을 나타냅니다.
    except <expression>, <expression>:
    

    다음으로 해석되어야 하는지

    except <type>, <type>:
    

    또는 다음으로 해석되어야 하는지

    except <type>, <name>:
    

    Python 2는 후자의 의미를 선택하지만, 그 대가로 전자를 다음과 같이 괄호로 묶어야 합니다.

    except (<type>, <type>):
    
  2. PEP가 명시한 바에 따라, PEP 352에 예외를 튜플로 취급하는 기능은 제거될 예정이므로 이 코드는 더 이상 작동하지 않습니다.
    except os.error, (errno, errstr):
    

    자동 언패킹이 더 이상 가능하지 않으므로, 튜플을 except 대상으로 사용할 수 있는 기능을 제거하는 것이 바람직합니다.

  3. PEP가 명시한 바에 따라, PEP 344에서 Python 3의 예외 인스턴스는 __traceback__ 속성을 갖게 됩니다. 해당 PEP의 미해결 문제 섹션에는 이 속성으로 인해 발생하는 가비지 컬렉션의 어려움을 설명하는 단락이 포함되어 있습니다. 즉, “예외 -> 트레이스백 -> 스택 프레임 -> 예외” 참조 순환으로 인해 다음 GC 실행 때까지 모든 지역 변수가 스코프에 유지됩니다. 이 PEP는 Python 3의 except 절에 정리 의미를 추가하여 이 문제를 해결하려 합니다. 이에 따라 대상 이름은 except 스위트의 끝에서 삭제됩니다.
  4. 다음 원칙인 “there should be one – and preferably only one – obvious way to do it”의 취지에 따라 중복 기능을 통합하는 것이 바람직합니다. 이를 위해 sys 모듈 [1]exc_value, exc_typeexc_traceback 속성은 동일한 정보를 제공하는 sys.exc_info()를 대신 사용하도록 제거됩니다. 이러한 속성은 이미 PEP 3100에서 제거 대상으로 열거되어 있습니다.

문법 변경

Python 3에서는 except 문에 대한 문법이 [4]에서

except_clause: 'except' [test [',' test]]

다음으로

except_clause: 'except' [test ['as' NAME]]

쉼표 토큰 대신 as를 사용하면 다음이

except (AttributeError, os.error):

예외 클래스의 튜플임을 명확히 이해할 수 있습니다. 이 새로운 구문은 Greg Ewing이 처음 제안했으며 [2] BDFL이 지지했습니다([2], [3]).

또한 as 다음 토큰을 test에서 NAME으로 제한하면 유효한 식별자만 except 대상으로 사용할 수 있습니다.

위 문법에서는 예외 클래스로 항상 괄호로 묶은 튜플이 필요하다는 점에 유의하십시오. 그렇게 하면 모호한 다음 구문이

except A, B:

Python 2.x와 3.x에서 서로 다른 의미를 가지므로 잡기 어려운 버그로 이어질 수 있지만, 3.x 코드에서는 합법적으로 나타날 수 없습니다.

의미 변경

관련 PEP 344와 관련된 가비지 컬렉션 문제를 해결하기 위해, Python 3의 except 문은 대상을 삭제하는 추가 바이트코드를 생성하여 참조 순환을 제거합니다. Phillip J. Eby [5]가 제안한 소스 간 변환은

try:
    try_body
except E as N:
    except_body
...

(Python 2.5 용어로) 다음과 같이 변환됩니다.

try:
    try_body
except E, N:
    try:
        except_body
    finally:
        N = None
        del N
...

구현은 이미 py3k(이전에는 “p3yk”라고 불림) 브랜치에 체크인되었습니다 [6].

호환성 문제

거의 모든 except 절을 변경해야 합니다. 식별자 대상을 사용하는 except 절은 다음에서 변경해야 합니다.

except E, N:

다음으로

except E as N:

튜플이 아니고 식별자도 아닌 대상을 사용하는 except 절(예: a.b.c[d])은 다음에서 변경해야 합니다.

except E, T:

다음으로

except E as t:
    T = t

이 두 경우 모두 Guido van Rossum의 2to3 유틸리티 [7]에서 except 수정자 [8]를 사용하여 처리할 수 있습니다.

튜플 대상을 사용하는 except 절은 사례별로 수동 변환해야 합니다. 이러한 변경에는 대개 예외 클래스 자체의 변경도 수반되어야 합니다. 일반적으로 이러한 변경은 자동화할 수 없지만, 2to3 유틸리티는 except 절의 대상이 튜플인 경우를 알려 주므로 변환을 간소화할 수 있습니다.

except 절이 끝난 후에도 예외 인스턴스를 유지해야 하는 상황은 다음과 같이 쉽게 변환할 수 있습니다.

try:
    ...
except E as N:
    ...
...

다음과 같이 변경됩니다.

try:
    ...
except E as N:
    n = N
    ...
...

이렇게 하면 블록 끝에서 N이 삭제될 때 n은 유지되므로 정상적으로 사용할 수 있습니다.

마지막으로 sys 모듈의 exc_type, exc_valueexc_traceback 특성을 사용하는 모든 코드를 제거해야 합니다. 이러한 특성은 각각 sys.exc_info()[0], sys.exc_info()[1]sys.exc_info()[2]로 대체할 수 있으며, 이 변환은 2to3sysexcattrs 수정자로 수행할 수 있습니다.

2.6 - 3.0 호환성

Python 2.6과 3.0 간의 향후 호환성을 지원하기 위해 except ... as ...: 구문이 2.x 계열로 백포트됩니다. 따라서 문법은 다음에서 변경됩니다.:

except_clause: 'except' [test [',' test]]

다음으로:

except_clause: 'except' [test [('as' | ',') test]]

except 문의 절 끝 정리 의미론은 2.x 계열 릴리스에 포함되지 않습니다.

미해결 문제

“sys.exc_info()” 대체 또는 제거

sys.exc_info()를 제거하거나 sys.exception 특성 또는 sys.get_exception() 함수로 대체하자는 아이디어는 python-3000에서 여러 차례 제기되었으며 ([9], [10]), PEP 344의 “미해결 문제” 절에서도 언급되었습니다.

sys.exc_info() 호출과 일부 특성 접근을 대체하는 2to3 수정자를 작성하는 일은 간단하지만, 정적 분석으로 sys.exc_info()의 값을 인자로 받는 함수를 찾아 수정하는 일은 훨씬 더 어렵습니다. 마찬가지로 이는 sys.exc_info()를 기준으로 정의된 모든 API의 문서를 다시 작성해야 하는 문제도 해결하지 못합니다.

구현

이 PEP는 리비전 53342 [11] 및 53349 [12]에서 구현되었습니다. 2.6에서 새로운 except 구문을 지원하는 기능은 리비전 55446 [13]에서 구현되었습니다.

참고 자료