핵심 원리: 하나의 try 블록에서는 단 하나의 except 절만 실행됩니다
파이썬에서 try 블록 안에서 예외가 발생하면, 여러 개의 except 절이 존재하더라도 조건에 맞는 단 하나의 except 절만 실행됩니다. 따라서 같은 try 블록 안의 어떤 except 절에서 발생시킨 예외를, 동일한 try 블록의 다른 except 절에서 다시 잡는 것은 불가능합니다.
예외를 더 상위(바깥쪽) 수준에서 처리하고 싶다면 중첩된(nested) try 블록을 사용해야 합니다.
중첩 try-except 블록 예제
아래 코드처럼 두 개의 try...except 블록을 중첩하여 작성할 수 있습니다:
try:
try:
1/0
except ArithmeticError as e:
if str(e) == "Zero division":
print("thumbs up")
else:
raise
except Exception as err:
print("thumbs down")
raise err
실행 결과
thumbs down
Traceback (most recent call last):
File "C:/Users/TutorialsPoint1/~.py", line 11, in <module>
raise err
File "C:/Users/TutorialsPoint1/~.py", line 3, in <module>
1/0
ZeroDivisionError: division by zero
코드 동작 과정 살펴보기
위 코드의 실행 흐름을 단계별로 정리하면 다음과 같습니다:
- 1/0 연산으로 인해 ZeroDivisionError가 발생합니다.
- 내부 except 절(ArithmeticError)이 이 예외를 잡지만, 에러 메시지가 "Zero division"과 일치하지 않으므로 else 분기의 bare raise 문이 현재 예외를 그대로 다시 발생(re-raise)시킵니다.
- 다시 던져진 예외는 같은 try 블록의 다른 except 절에서는 절대 잡히지 않으며, 바깥쪽 try 블록의 except Exception 절로 전달됩니다.
- 바깥쪽 except 절이 "thumbs down"을 출력한 뒤, raise err 문으로 예외를 한 번 더 발생시키기 때문에 프로그램은 최종적으로 비정상 종료되며 트레이스백이 출력됩니다.
정리
파이썬 공식 튜토리얼에도 명시되어 있듯이, 하나의 try 문에는 단 하나의 예외만 잡힙니다(catch). 동일한 try 블록 내의 다른 except 절에서 예외를 처리하는 것은 불가능하며, 반드시 중첩 try 구조를 사용해야 합니다. 또한 인자 없는 raise 문은 현재 처리 중인 예외를 그대로 다시 던지는 역할을 하므로, 예외를 상위 계층으로 전달할 때 매우 유용하게 활용할 수 있습니다.