HOWTO · Python
Python에서 예외를 출력하는 방법
Python에서 예외를 출력하고, 메시지와 전체 traceback을 구분하며, 일반적인 예외 처리 실수를 피하는 방법을 알아봅니다.
이 페이지의 내용
오류 메시지만 필요하면 print(exception)을 사용합니다. Python 에서 오류를 발생시킨 파일과 줄을 포함한 전체 traceback이 필요하면 활성 except 블록 안에서 traceback.print_exc()를 사용합니다. 예외별 처리를 좁게 유지하고 보존해야 하는 진단에는 print() 대신 로깅을 사용합니다.
예외 메시지 출력
예외를 변수로 받아 print()에 전달합니다. 무엇이 잘못되었는지 보여 주는 가장 짧은 방법입니다.
try:
result = 10 / 0
except ZeroDivisionError as exc:
print("Could not calculate result:", exc)
출력:
Could not calculate result: division by zero
예외 객체(Exception 객체)는 메시지 문자열로 변환됩니다. 이 예제는 ZeroDivisionError만 구체적으로 처리하므로 관련 없는 프로그래밍 오류를 숨길 가능성이 낮습니다. 여러 오류를 동일하게 처리해야 한다면 except (TypeError, ValueError) as exc:처럼 튜플로 타입을 나열합니다.
전체 traceback 출력
메시지만으로는 오류가 발생한 위치를 알 수 없을 수 있습니다. Python의 내장 traceback 모듈을 가져오고 핸들러가 활성화된 동안 print_exc()를 호출합니다.
import traceback
try:
values = [1, 2]
value = values[3]
except IndexError:
traceback.print_exc()
출력에는 예외 유형, 메시지, 파일 및 실패한 줄이 포함됩니다. 여러 중첩 함수 호출에서 예외가 발생했다면 메시지보다 traceback이 더 유용합니다.
print_exc()는 현재 처리 중인 예외를 읽습니다. except 블록이 끝난 뒤나 활성 예외가 없을 때 호출해도 이전 traceback을 복구하지 못하며 NoneType: None을 출력할 수 있습니다. 호출을 핸들러 안에 두거나 예외를 저장한 뒤 명시적인 제어를 위해 print_exception()을 사용합니다.
traceback 형식 명시적으로 제어
traceback.print_exception()은 예외 객체를 받고 선택한 스트림에 쓸 수 있습니다. 예외를 형식화하거나 다른 곳으로 보내야 할 때 유용합니다.
import sys
import traceback
try:
int("not a number")
except ValueError as exc:
traceback.print_exception(exc, file=sys.stdout)
즉시 출력하지 않고 텍스트를 만들려면 traceback.format_exception(exc)를 사용합니다.
import traceback
try:
raise RuntimeError("configuration is missing")
except RuntimeError as exc:
formatted = "".join(traceback.format_exception(exc))
print(formatted)
traceback 함수는 기본적으로 예외 연결을 보존합니다. 따라서 raise ... from ... 연결은 원래 예외와 새 예외를 모두 표시할 수 있습니다. 출력 계약에서 요구할 때만 traceback을 제한하거나 연결을 끄십시오. 컨텍스트를 제거하면 진단이 어려워집니다.
사용자 정의 예외와 로깅
호출자가 도메인 오류와 내장 오류를 구분해야 한다면 사용자 정의 예외를 정의합니다. 해당 타입을 잡고 같은 방식으로 메시지를 출력합니다.
class ConfigurationError(Exception):
pass
try:
raise ConfigurationError("API key is missing")
except ConfigurationError as exc:
print("Configuration failed:", exc)
애플리케이션이나 서비스에서는 핸들러 안의 logging.exception()을 우선합니다. 메시지와 활성 traceback을 기록하며 로그 핸들러가 파일이나 모니터링 시스템으로 보낼 수 있습니다.
import logging
try:
load_settings()
except Exception:
logging.exception("Loading settings failed")
load_settings()를 실패할 수 있는 작업으로 바꾸십시오. 이 예제는 로깅 경계에서 의도적으로 넓은 Exception을 잡습니다. 일반 로직에서는 실제로 처리할 수 있는 구체적인 예외 유형만 잡아야 합니다.
일반적인 실수와 FAQ
- 유형이 없는
except:는KeyboardInterrupt와SystemExit도 잡습니다.BaseException하위 클래스를 처리할 특별한 이유가 없다면 피하십시오. - 프로그램이 유효한 결과를 만들 수 없는데 일반 메시지만 출력하고 조용히 계속하지 마십시오. 예외를 다시 발생시키거나 명시적인 실패를 반환합니다.
type(exc)는 구체적인 클래스,str(exc)는 사람이 읽는 메시지,repr(exc)는 더 진단적인 표현을 보여 줍니다.- 로그로 보낼 출력이면 핸들러 안에서
logging.exception()을 사용합니다. 짧은 대화형 진단에는print(exc)면 충분합니다. traceback.print_exc()는 현재 처리 중인 예외용입니다. 객체를 보관하고 형식이나 출력을 제어하려면traceback.print_exception(exc)가 더 명확합니다.
이 패턴은 Python의 내장 예외 기능을 사용하므로 서드파티 패키지가 필요하지 않습니다. 메시지, 전체 호출 경로, 형식화된 텍스트 또는 지속적인 애플리케이션 로그 중 무엇이 필요한지에 따라 선택합니다.