Python에서 예외 메시지를 올바르게 얻는 방법


104

Python의 표준 라이브러리 구성 요소에서 예외 메시지를 얻는 가장 좋은 방법은 무엇입니까?

어떤 경우에는 다음 message과 같은 필드 를 통해 얻을 수 있음을 알았습니다 .

try:
  pass
except Exception as ex:
  print(ex.message)

그러나 어떤 경우에는 (예 : 소켓 오류의 경우) 다음과 같이해야합니다.

try:
  pass
except socket.error as ex:
  print(ex)

이러한 상황을 대부분 처리 할 수있는 표준 방법이 있는지 궁금합니다.


1
두 가지 다른 것을 결합하고 있습니다- 오류가 속성 과 함께 제공되는지 여부에 관계없이 except Foo as bar:동일합니다 except Foo, bar:(전자는 더 새롭고 3.x에서 계속 작동합니다) message.
jonrsharpe

1
@FrozenHeart .message오류에 대한 액세스 가 표준 방식 인지 여부를 묻고 있습니까?
Anand S Kumar

두 번째 예 print(msg)는 바로 가기입니다print(str(msg))
Salo

@Anand S Kumar 예. 어떤 경우에도 작동합니까?
FrozenHeart 2015 년

6
액세스 message가 더 이상 사용되지 않는다고 생각 합니다.
Jonathon Reinhart 2015 년

답변:


102

내장 오류 에 대한 문서를 보면 대부분의 Exception클래스가 첫 번째 인수를 message속성 으로 할당하는 것을 볼 수 있습니다. 하지만 모두가 그렇게하는 것은 아닙니다.

특히 EnvironmentError(하위 클래스 IOErrorOSError)에는의 첫 번째 인수 errno,의 두 번째 인수 가 strerror있습니다. 없습니다 message... strerror일반적으로 message.

보다 일반적으로의 하위 클래스는 Exception원하는 모든 작업을 수행 할 수 있습니다. message속성 이있을 수도 있고 없을 수도 있습니다 . 향후 내장 Exceptionmessage속성 이 없을 수 있습니다 . Exception타사 라이브러리 또는 사용자 코드에서 가져온 모든 하위 클래스에는 message속성 이 없을 수 있습니다 .

이를 처리하는 적절한 방법은 Exception잡으려 는 특정 하위 클래스 를 식별 한 다음를 사용하여 모든 것 대신 해당 하위 클래스 만 잡은 except Exception다음 원하는대로 특정 하위 클래스가 정의하는 속성을 활용하는 것입니다.

당신이 print무언가 를해야한다면 , 나는 그것이 속성 Exception이 있든 없든, 당신이 원하는 것을 할 가능성이 가장 높다고 생각합니다 message.

원하는 경우 메시지 속성을 확인할 수도 있습니다. 이처럼 복잡해 보이기 때문에 실제로 제안하지는 않습니다.

try:
    pass
except Exception as e:
    # Just print(e) is cleaner and more likely what you want,
    # but if you insist on printing message specifically whenever possible...
    if hasattr(e, 'message'):
        print(e.message)
    else:
        print(e)

답변 해주셔서 감사합니다. str(ex)대신 사용하는 특별한 이유가 ex있습니까?
FrozenHeart 2015 년

4
@FrozenHeart- print()자동으로 전화 str()합니다. str()문자열을 호출 하면 문자열 자체를 반환하기 때문에 무해하지만 수동으로 직접 호출 할 이유는 없습니다 .
ArtOfWarfare 2015 년

1
@ArtOfWarfare str()메시지가 유형이면 문제가있을 수 있다고 생각 합니다 unicode.
kratenko

39

@artofwarfare 에서 제공하는 답변을 개선하기 위해 여기에 message속성 을 확인 하고 인쇄하거나 Exception객체를 폴백으로 인쇄 하는 더 깔끔한 방법이 있습니다 .

try:
    pass 
except Exception as e:
    print getattr(e, 'message', repr(e))

에 대한 호출 repr은 선택 사항이지만 일부 사용 사례에서 필요합니다.


업데이트 # 1 :

@MadPhysicist 의 의견에 따라를 호출 해야하는 이유에 대한 증거 repr가 있습니다. 인터프리터에서 다음 코드를 실행 해보십시오.

try:
    raise Exception 
except Exception as e:
    print(getattr(e, 'message', repr(e)))
    print(getattr(e, 'message', str(e)))

업데이트 # 2 :

다음은 Python 2.7 및 3.5에 대한 구체적인 데모입니다. https://gist.github.com/takwas/3b7a6edddef783f2abddffda1439f533


1
getattr전달 된 객체에 요청 된 속성이없는 경우 예외가 발생합니다. 당신이 그런 짓을하고 싶었다면, 나는 당신의 세번째 인수를 사용한다고 생각 getattr이 등을 : print getattr(e, 'message', e). 내가 한 것보다 더 낫다. 또 다른 옵션은 print(e.message if hasattr(e, 'message') else e).
ArtOfWarfare

2
당신은 거의 확실하게 원하는 것 str대신에 repr.
Mad Physicist

2
에 비해 str, repr단지 클래스 이름을 추가합니다. 대신에 사용하는 repr, 내가 사용하는 제안 것입니다 print('{e.__class__.__name__}: {e}'.format(e=e)). 인쇄 출력물이 깨끗하고 인상 자체의 출력물에 부착됩니다.
kadee

1
위의 내용을 바탕으로 가장 유용하다는 것을 알았습니다'{e.__class__.__module__}.{e.__class__.__name__}: {e}'
shadi

1
감사!! repr(e)현재로서는 특정 상황에서 발견 한 오류에 대해 최소한의 정보를 인쇄하는 데 도움이되는 유일한 솔루션이었습니다. repr(e)yields KeyError(0,)(오류가 무엇인지), 반면 str(e)또는 e.message산출물은 0각각 또는 전혀 산출 하지 않습니다.
FlorianH 2010

0

나는 같은 문제가 있었다. 가장 좋은 해결책은 log.exception을 사용하는 것입니다. 그러면 다음과 같은 스택 추적 및 오류 메시지가 자동으로 출력됩니다.

try:
    pass
    log.info('Success')
except:
    log.exception('Failed')

2
무엇입니까 log? 방금 import logPython 2.7.13을 시도했는데 해당 이름의 모듈이 없다는 메시지가 표시되었습니다. 당신이 추가 한 것입니까 아니면 pip새로운 버전의 파이썬에 추가 되었습니까? ...)
ArtOfWarfare

7
그는 아마도 파이썬에서 로깅 모듈을 사용하고 로그 변수로 로거를 인스턴스화하고있을 것입니다. import logging\ nlog = logging.getLogger(__name__)
Josepas 2019

0

나도 같은 문제가 있었다. 이것을 파헤 치면 Exception 클래스에 예외 args를 생성하는 데 사용 된 인수를 캡처 하는 속성 이 있음을 발견했습니다 . except가 부분 집합으로 잡을 예외의 범위를 좁 히면, 그것들이 어떻게 생성되었는지, 그리고 어떤 인수가 메시지를 포함하는지 결정할 수 있어야합니다.

try:
   # do something that may raise an AuthException
except AuthException as ex:
   if ex.args[0] == "Authentication Timeout.":
      # handle timeout
   else:
      # generic handling
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.