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

Python 개선 제안 한국어 번역

PEP 3109 – Python 3000에서 예외 발생시키기

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


Table of Contents

번역·라이선스 안내

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

초록

이 PEP는 코드 잡음과 언어의 크기를 모두 줄이기 위해 Python의 예외 발생 메커니즘에 변경 사항을 도입합니다.

근거

Python의 지침이 되는 격언 중 하나는 “이를 수행하는 명백한 방법은 하나, 가능하면 오직 하나여야 합니다”입니다. Python 2.x의 raise 문은 동일한 생각을 표현하는 여러 방법을 허용하므로 이 원칙을 위반합니다. 예를 들어, 다음 문은 서로 동등합니다.

raise E, V

raise E(V)

raise 문에는 예외에 임의의 트레이스백을 연결할 수 있는 세 번째 형식도 있습니다 [1].

raise E, V, T

여기서 T는 트레이스백입니다. 관련 PEP 344에 명시된 바와 같이, Python 3.x의 예외 객체는 __traceback__ 속성을 가지며, 이에 따라 세 표현식 raise 문을 다음과 같이 변환할 수 있습니다:

raise E, V, T

다음으로 변환됩니다.

e = E(V)
e.__traceback__ = T
raise e

이러한 변환을 사용하면 raise 문의 형식을 네 가지에서 두 가지로 줄일 수 있습니다.

  1. raise (인자 없음)는 except 절에서 현재 활성화된 예외를 다시 발생시키는 데 사용합니다.
  2. raise EXCEPTION은 새 예외를 발생시키는 데 사용합니다. 이 형식에는 두 가지 하위 변형이 있습니다. EXCEPTION은 예외 클래스이거나 예외 클래스의 인스턴스일 수 있으며, 유효한 예외 클래스는 BaseException과 그 서브클래스입니다(PEP 352). EXCEPTION이 서브클래스이면 인자 없이 호출하여 예외 인스턴스를 얻습니다.

    그 밖의 것을 발생시키면 오류입니다.

A.M.이 지적한 바와 같이, 이러한 통합을 통해 더욱 실질적인 추가 이점도 얻을 수 있습니다. Kuchling [2].

PEP 8 doesn't express any preference between the
two forms of raise statements:
raise ValueError, 'blah'
raise ValueError("blah")

I like the second form better, because if the exception arguments
are long or include string formatting, you don't need to use line
continuation characters because of the containing parens.

BDFL도 이에 동의했으며 [3], 여러 raise 형식의 통합을 지지했습니다.

문법 변경

Python 3에서는 raise문의 문법이 [1]에서 다음과 같이 변경됩니다.

raise_stmt: 'raise' [test [',' test [',' test]]]

다음으로

raise_stmt: 'raise' [test]

내장 타입 변경

예외 발생과 관련되어 있으므로 제너레이터 객체의 throw() 메서드 시그니처가 변경되어 선택적 두 번째 및 세 번째 매개변수가 제거됩니다. 따라서 시그니처는 (PEP 342) 다음과 같이 변경됩니다.

generator.throw(E, [V, [T]])

다음으로

generator.throw(EXCEPTION)

여기서 EXCEPTIONBaseException의 서브클래스이거나 BaseException의 서브클래스 인스턴스입니다.

의미 변경

Python 2에서는 다음 raise 문이 유효합니다.

raise ((E1, (E2, E3)), E4), V

인터프리터는 튜플의 첫 번째 요소를 예외 타입으로(재귀적으로) 취급하므로, 위 문은 다음 문과 완전히 동등해집니다.

raise E1, V

Python 3.0부터는 이와 같이 튜플을 발생시키는 기능이 제거됩니다. 이 변경으로 raise 문은 제너레이터 객체의 throw() 메서드와 일치하게 되며, 해당 메서드는 이미 이를 허용하지 않습니다.

호환성 문제

두 표현식 및 세 표현식 raise 문을 모두 수정해야 하며, 제너레이터의 두 표현식 및 세 표현식 throw() 호출도 모두 수정해야 합니다. 다행히 이 경우 Python 2.x에서 Python 3.x로의 변환은 간단하며, Guido van Rossum의 2to3 유틸리티 [4]에서 raisethrow 수정 도구([5], [6])를 사용하여 기계적으로 처리할 수 있습니다.

다음과 같이 변환됩니다.

  1. 표현식이 0개 또는 1개인 raise 문은 그대로 둡니다.
  2. 두 표현식 raise 문은 다음에서
    raise E, V
    

    다음으로 변환됩니다.

    raise E(V)
    

    두 표현식 throw() 호출은 다음에서

    generator.throw(E, V)
    

    다음으로 변환됩니다.

    generator.throw(E(V))
    

    이 변환에 관한 주의 사항은 5번 항목을 참조하십시오.

  3. 세 표현식 raise 문은 다음에서
    raise E, V, T
    

    다음으로 변환됩니다.

    e = E(V)
    e.__traceback__ = T
    raise e
    

    세 표현식 throw() 호출은 다음에서

    generator.throw(E, V, T)
    

    다음으로 변환됩니다.

    e = E(V)
    e.__traceback__ = T
    generator.throw(e)
    

    이 변환에 관한 주의 사항은 5번 항목을 참조하십시오.

  4. E가 튜플 리터럴인 두 표현식 및 세 표현식 raise 문은 2to3raise 수정 도구를 사용하여 자동으로 변환할 수 있습니다. 함수 호출의 결과와 같이 E가 리터럴이 아닌 튜플인 raise 문은 수동으로 변환해야 합니다.
  5. E가 예외 클래스이고 V가 예외 인스턴스인 두 표현식 및 세 표현식 raise 문은 특별한 주의가 필요합니다. 이러한 경우는 두 가지 유형으로 나뉩니다.
    1. 0인자 raise 문의 긴 형식으로서의 raise E, V 예를 들어 F가 E의 서브클래스라고 가정하면
      try:
          something()
      except F as V:
          raise F(V)
      except E as V:
          handle(V)
      

      다음과 같이 표현하는 것이 더 좋습니다.

      try:
          something()
      except F:
          raise
      except E as V:
          handle(V)
      
    2. 예외를 다른 클래스로 “캐스팅”하는 방법으로서의 raise E, V distutils.compiler.unixcompiler의 예를 들면
      try:
          self.spawn(pp_args)
      except DistutilsExecError as msg:
          raise CompileError(msg)
      

      다음과 같이 표현하는 것이 더 좋습니다.

      try:
          self.spawn(pp_args)
      except DistutilsExecError as msg:
          raise CompileError from msg
      

      관련 PEP 344에서 도입된 raise ... from ... 구문을 사용합니다.

구현

이 PEP는 리비전 57783 [7]에서 구현되었습니다.

참고 자료