메인 프로그램에서 호출 한 함수가 있습니다 :
try:
someFunction()
except:
print "exception happened!"
그러나 함수 실행 중에 예외가 발생하므로 해당 except
부분으로 이동합니다 .
someFunction()
예외가 발생한 원인을 정확히 어떻게 알 수 있습니까?
답변
다른 답변은 일반적인 예외를 잡아서는 안된다고 지적하지만 아무도 규칙을 어길 수있는 시점을 이해하는 데 필수적인 이유를 말하고 싶지 않습니다. 여기 에 설명이 있습니다. 기본적으로 숨기지 않습니다.
- 오류가 발생했다는 사실
- 발생한 오류의 세부 사항 ( 반 패턴 숨기기 오류 )
따라서 이러한 작업을 수행하지 않는 한 일반적인 예외를 잡는 것이 좋습니다. 예를 들어 다음과 같은 다른 방법으로 예외에 대한 정보를 사용자에게 제공 할 수 있습니다.
- GUI에서 대화 상자로 예외 표시
- 멀티 스레딩 또는 멀티 프로세싱 응용 프로그램에서 작업자 스레드 또는 프로세스에서 제어 스레드 또는 프로세스로 예외 전송
그렇다면 일반적인 예외를 잡는 방법은 무엇입니까? 몇 가지 방법이 있습니다. 예외 객체를 원한다면 다음과 같이하십시오.
try:
someFunction()
except Exception as ex:
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
print message
놓칠 수없는 방식으로 사용자의주의를 끌 도록 하십시오 message
! 위와 같이 메시지가 다른 많은 메시지에 묻혀 있으면 인쇄하기에 충분하지 않을 수 있습니다. 사용자의 관심을 끌지 못하는 것은 모든 예외를 삼키는 데 큰 영향을 미치며,이 페이지의 답변을 읽은 후 사라져야 할 인상이 있다면 이것이 좋지 않은 것 입니다. 를 사용하여 except 블록 끝내기raise
statement로 발견 된 예외를 투명하게 다시 발생시켜 문제를 해결할 수 있습니다.
위와 except:
인수없이 그냥 사용하는 것의 차이점 은 두 가지입니다.
- 베어
except:
는 검사 할 예외 개체를 제공하지 않습니다. - 예외는
SystemExit
,KeyboardInterrupt
그리고GeneratorExit
일반적으로 당신이 원하는 무엇을 위의 코드에 의해 잡힌되지 않습니다. 예외 계층을 참조하십시오 .
예외를 잡지 않으면 동일한 스택 추적을 원한다면 다음과 같이 얻을 수 있습니다 (여전히 except 절 안에 있음).
import traceback
print traceback.format_exc()
logging
모듈 을 사용하는 경우 다음과 같이 예외를 메시지와 함께 로그에 인쇄 할 수 있습니다.
import logging
log = logging.getLogger()
log.exception("Message for you, sir!")
더 깊이 파고 스택을 검사하려면 변수 등을 살펴보고 except 블록 내부의 모듈 post_mortem
기능을 사용하십시오 pdb
.
import pdb
pdb.post_mortem()
나는이 마지막 방법이 버그를 사냥 할 때 귀중한 것으로 나타났습니다.
답변
예외 개체가 속한 클래스의 이름을 가져옵니다.
e.__class__.__name__
print_exc () 함수를 사용하면 모든 오류 메시지에 대한 필수 정보 인 스택 추적을 인쇄합니다.
이처럼 :
from traceback import print_exc
class CustomException(Exception): pass
try:
raise CustomException("hi")
except Exception, e:
print 'type is:', e.__class__.__name__
print_exc()
# print "exception happened!"
다음과 같이 출력됩니다 :
type is: CustomException
Traceback (most recent call last):
File "exc.py", line 7, in <module>
raise CustomException("hi")
CustomException: hi
그리고 인쇄 및 분석 후 코드는 예외를 처리하지 않고 다음을 실행하기로 결정할 수 있습니다 raise
.
from traceback import print_exc
class CustomException(Exception): pass
def calculate():
raise CustomException("hi")
try:
calculate()
except Exception, e:
if e.__class__ == CustomException:
print 'special case of', e.__class__.__name__, 'not interfering'
raise
print "handling exception"
산출:
special case of CustomException not interfering
그리고 인터프리터는 예외를 인쇄합니다.
Traceback (most recent call last):
File "test.py", line 9, in <module>
calculate()
File "test.py", line 6, in calculate
raise CustomException("hi")
__main__.CustomException: hi
raise
원래 예외 후에 계속해서 호출 스택을 계속 전파합니다. ( 가능한 함정에주의하십시오 ) 새로운 예외를 제기하면 새로운 (더 짧은) 스택 추적이 필요합니다.
from traceback import print_exc
class CustomException(Exception): pass
def calculate():
raise CustomException("hi")
try:
calculate()
except Exception, e:
if e.__class__ == CustomException:
print 'special case of', e.__class__.__name__, 'not interfering'
#raise CustomException(e.message)
raise e
print "handling exception"
산출:
special case of CustomException not interfering
Traceback (most recent call last):
File "test.py", line 13, in <module>
raise CustomException(e.message)
__main__.CustomException: hi
역 추적 에 원래 예외의 원점 인 calculate()
line 함수가 포함되지 않은 방법에 주목하십시오 .9
e
답변
일반적으로 예외 try: ... except
가 너무 광범위하므로 가능한 모든 예외를 포착해서는 안됩니다 . 어떤 이유로 든 일어날 것으로 예상되는 것들을 잡아라. 예를 들어 디버깅하는 동안 일부 문제에 대해 더 자세히 알고 싶다면 실제로해야합니다.
try:
...
except Exception as ex:
print ex # do whatever you want for debugging.
raise # re-raise exception.
답변
somefunction
코딩 된 레거시 기능이 매우 나쁜 경우 가 아니라면 원하는 것을 요구하지 않아도됩니다.
여러 except
절을 사용 하여 다른 예외를 다른 방식으로 처리 하십시오 .
try:
someFunction()
except ValueError:
# do something
except ZeroDivision:
# do something else
요점은 일반적인 예외를 잡아서는 안되며 필요한 예외 만 잡아야한다는 것입니다. 예기치 않은 오류나 버그를 숨기고 싶지 않다고 확신합니다.
답변
대부분의 대답은 except (…) as (…):
구문을 가리키고 있지만 (정확히), 동시에 코끼리가 sys.exc_info()
기능 하는 방에있는 코끼리에 대해 이야기하고 싶은 사람은 없습니다 . sys 모듈 (강조 광산) 의 문서 에서 :
이 함수는 현재 처리중인 예외에 대한 정보를 제공하는 세 가지 값의 튜플을 반환합니다.
(…)
스택의 어느 곳에서나 예외가 처리되지 않으면 3 개의 None 값을 포함하는 튜플이 반환됩니다. 그렇지 않으면 리턴 된 값은 (type, value, traceback)입니다. 의미는 다음과 같습니다. type은 처리중인 예외 유형 (BaseException의 서브 클래스)을 가져옵니다 . value는 예외 인스턴스 (예외 유형의 인스턴스)를 가져옵니다. traceback은 예외가 원래 발생한 지점에서 콜 스택을 캡슐화하는 traceback 객체를 가져옵니다 (참조 매뉴얼 참조).
어떤 유형의 예외가 발생했는지 어떻게 알 수 있습니까?sys.exc_info()
의 원래 질문에 대한 가장 직접적인 대답으로 간주 될 수 있다고 생각합니다 .
답변
시도 : 예외를 제외하고 someFunction ()
#this is how you get the type
excType = exc.__class__.__name__
#here we are printing out information about the Exception
print 'exception type', excType
print 'exception msg', str(exc)
#It's easy to reraise an exception with more information added to it
msg = 'there was a problem with someFunction'
raise Exception(msg + 'because of %s: %s' % (excType, exc))
답변
이 답변은 디버깅에는 적합하지만 프로그래밍 방식으로 예외를 테스트하는 경우 isinstance(e, SomeException)
하위 클래스 SomeException
도 테스트하므로 편리 하므로 예외 계층에 적용되는 기능을 만들 수 있습니다.