한 줄에 여러 예외를 잡아라 (블록 제외)


2755

나는 내가 할 수 있다는 것을 안다.

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

나는 또한 이것을 할 수있다 :

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

그러나 두 가지 다른 예외 내에서 동일한 작업을 수행하려면 지금 생각할 수있는 가장 좋은 방법은 다음과 같습니다.

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

이 예외를 수행 할 수있는 방법이 있습니까? (두 예외 모두에서 수행하는 작업은이므로 say please)

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

이제는 다음 구문과 일치하므로 실제로 작동하지 않습니다.

try:
    # do something that may fail
except Exception, e:
    # say please

따라서 두 가지 예외를 포착하려는 노력이 정확히 이루어지지 않았습니다.

이것을 할 수있는 방법이 있습니까?


6
파이썬 3에서 후자는 더 이상 유효한 구문이 아닙니다.
gerrit

답변:


3723

에서 파이썬 문서 :

except 절은 여러 예외를 괄호로 묶은 튜플로 명명 할 수 있습니다 (예 :

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

또는 Python 2의 경우에만 :

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

쉼표로 변수에서 예외를 분리하면 Python 2.6 및 2.7에서는 계속 작동하지만 더 이상 사용되지 않으며 Python 3에서는 작동하지 않습니다. 이제을 사용해야합니다 as.


9
나는 그것을 시도했다 ...와 함께 list결과 TypeError. tuple잡기가 예상대로 작동 하려면 오류가 있어야합니다 .
BallpointBen

4
이 경우에 튜플이 필요하다는 것이 문서화되어 있음을 분명히 알았을 때 왜 목록을 사용했을까요?
mechanical_meat

6
"괄호로 묶인 튜플"이 단순히 구문 적인지 또는 선의의 튜플이 필요한지 여부는 불분명했습니다. 다른 곳에서 괄호없이 튜플을 만든 다음 except줄에 사용할 수 있기 때문에 "Parenthesized"가 잘못되었습니다 . except행 에서 작성된 경우에만 괄호로 묶어야합니다 .
BallpointBen

5
@JosephBani, 제너레이터 표현식은 어떻습니까?
jammertheprogrammer

12
@JosephBani 전혀 사실이 아닙니다. 에서은 2 + (x * 2), (x * 2)확실히 튜플이 아니다. 괄호는 일반적인 그룹 구성입니다. 튜플의 정의 특성은 쉼표 가 포함되어 있다는 것입니다 . Python 설명서를 참조하십시오 . "실제로 괄호가 아닌 튜플을 만드는 쉼표입니다."
Soren Bjornstad

314

한 줄에 여러 예외를 잡는 방법 (블록 제외)

이 작업을 수행:

try:
    may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
    handle(error) # might log or have some other default behavior...

쉼표를 사용하여 오류 객체를 이름에 할당 한 이전 구문으로 인해 괄호가 필요합니다. as키워드는 할당에 사용됩니다. 오류 개체에 어떤 이름이든 사용할 수 있습니다 error. 개인적으로 선호합니다 .

모범 사례

현재와 ​​파이썬과 호환되는 방식으로이 작업을 수행하려면 Exception을 쉼표로 분리하고 괄호로 묶어 예외 인스턴스를 변수 이름으로 할당 한 이전 구문과 구별하기 위해 Exception 유형을 따라야합니다. 반점.

간단한 사용법의 예는 다음과 같습니다.

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    sys.exit(0)

버그를 숨기지 않기 위해 이러한 예외 만 지정하고 있습니다.이 경우 전체 스택 추적을 기대합니다.

https://docs.python.org/tutorial/errors.html에 설명되어 있습니다.

예외를 변수에 할당 할 수 있습니다 ( e일반적이지만 예외 처리가 길거나 IDE에서 내 선택 항목보다 더 큰 선택 항목 만 강조 표시하는 경우 더 자세한 변수를 선호 할 수 있습니다). 인스턴스에는 args 속성이 있습니다. 예를 들면 다음과 같습니다.

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError) as err: 
    print(err)
    print(err.args)
    sys.exit(0)

Python 3 err에서 except블록이 끝나면 객체가 범위를 벗어납니다 .

더 이상 사용되지 않음

쉼표로 오류를 지정하는 코드가 표시 될 수 있습니다. Python 2.5 및 이전 버전에서 사용할 수있는 유일한 형식 인이 사용법은 더 이상 사용되지 않으며 Python 3에서 코드가 이전 버전과 호환되도록하려면 구문을 업데이트하여 새 양식을 사용해야합니다.

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    sys.exit(0)

코드베이스에 쉼표 이름이 할당되어 있고 Python 2.5 이상을 사용하는 경우 업그레이드 할 때 코드가 호환되도록 새로운 방식으로 전환하십시오.

suppress컨텍스트 매니저

허용되는 답변은 실제로 최소 4 줄의 코드입니다.

try:
    do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

try, except, pass라인은 단일 라인에서 처리 할 수 있습니다 파이썬 3.4에서 사용할 억제 컨텍스트 매니저 :

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

따라서 pass특정 예외 를 원하면을 사용하십시오 suppress.


2
좋은 또한 suppress단지 것보다 더 읽기 많은, passexcept
반죽 공예

50

에서 파이썬 문서 -> 8.3 예외 처리 :

try문은 다른 예외 핸들러를 지정하는 데 더 많은 조항을 제외하고 하나보다 수 있습니다. 최대 하나의 핸들러가 실행됩니다. 핸들러는 동일한 try 문의 다른 핸들러가 아니라 해당 try 절에서 발생하는 예외 만 처리합니다. except 절은 여러 예외의 이름을 괄호로 묶은 튜플로 지정할 수 있습니다. 예를 들면 다음과 같습니다.

except (RuntimeError, TypeError, NameError):
    pass

이 튜플 주위의 괄호는 필수 입니다. 현대 파이썬에서 ValueError, e:일반적으로 쓰여지는 구문 except ValueError as e:(아래 설명 참조)이 제외 되었기 때문 입니다. 이전 구문은 이전 버전과의 호환성을 위해 계속 지원됩니다. 이 수단은 except RuntimeError, TypeError같지 않습니다 except (RuntimeError, TypeError):만에 except RuntimeError as TypeError:있는 당신이 원하는 없습니다.


35

많은 수의 예외를 자주 사용하는 경우 튜플을 미리 정의 할 수 있으므로 여러 번 다시 입력 할 필요가 없습니다.

#This example code is a technique I use in a library that connects with websites to gather data

ConnectErrs  = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)

def connect(url, data):
    #do connection and return some data
    return(received_data)

def some_function(var_a, var_b, ...):
    try: o = connect(url, data)
    except ConnectErrs as e:
        #do the recovery stuff
    blah #do normal stuff you would do if no exception occurred

노트:

  1. 또한 사전 정의 된 튜플의 예외 이외의 다른 예외를 포착해야하는 경우 다른 except 블록을 정의해야합니다.

  2. 전역 변수를 허용 할 수 없다면 main ()에서 변수를 정의하고 필요한 곳으로 전달하십시오 ...


17

이 작업을 수행하는 방법 중 하나는

try:
   You do your operations here;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   If there is any exception from the given exception list, 
   then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

또 다른 방법은 except블록으로 실행되는 작업을 수행하는 메소드를 작성하고 작성한 모든 except블록을 통해 호출하는 것입니다 .

try:
   You do your operations here;
   ......................
except Exception1:
    functionname(parameterList)
except Exception2:
    functionname(parameterList)
except Exception3:
    functionname(parameterList)
else:
   If there is no exception then execute this block. 

def functionname( parameters ):
   //your task..
   return [expression]

나는 두 번째 방법이 이것을하는 가장 좋은 방법은 아니라는 것을 알고 있지만,이 일을하는 많은 방법을 보여주고 있습니다.


두 번째 예외를 사용하고 있는데, 각각 다르게 처리해야하는 두 가지 예외가 있기 때문입니다. 그렇게하는 데 문제가 있습니까?
majikman

@majikman 두 개의 예외에 대해 자신을 반복하지 않고 같은 일을 할 때 각각 동일한 함수를 호출하는 여러 절을 가진 두 번째 방법은 최선이 아닙니다. (올바른 방법은 다른 답변을 참조하십시오). 그러나 except예외를 다르게 처리하려면 여러 절이있는 것이 일반적입니다.
시조
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.