예외
예외(Exceptioin)는 프로그램 실행 중 발생할 수 있는 예상치 못한 문제 또는 오류 상황을 의미한다.
예외가 발생하면 프로그램은 중단되기 때문에 이를 적절하게 처리하여 중단을 방지하거나 오류에 대한 정보를 사용자에게 제공해야 한다.
int(10 / 3)
print(5 / 0)
print(4 / 2)
# ZeroDivisionError: division by zero
# 둘째줄 코드에서 예외가 발생하고 프로그램은 세번째줄로 넘어가지않고 중단된다.
예외 계층 구조
BaseException
BaseException
├── Exception ← 우리가 보통 사용하는 예외
│ ├── ValueError
│ ├── TypeError
│ ├── ZeroDivisionError
│ └── ...
├── KeyboardInterrupt
└── SystemExit
👉 BaseException이 따로 있는 이유는 “진짜 에러”와 “프로그램 제어용 이벤트”를 구분하기 위해서이다.
1. Exception
코드 실행 중 발생한 일반적인 오류
- 0으로 나누기
- 잘못된 타입
- 값 오류
2. KeyboardInterrupt
사용자가 Ctrl + C 눌렀을 때 발생
👉 프로그램을 강제로 멈추는 신호
3. SystemExit
프로그램 종료 요청
👉 내부적으로 exit() 호출 시 발생
👉 KeyboardInterrupt와 SystemExit는 사실 '에러'가 아니라 프로그램을 멈추거나 종료하기 위한 신호
예외 처리 기본 구조
try:
# 예외가 발생할 가능성이 있는 코드
except ExceptionType1: # 'ExceptionType1'에는 실제 예외 유형이 들어갑니다.
# ExceptionType1 예외가 발생했을 때 실행될 코드
except ExceptionType2: # 'ExceptionType2'에는 다른 예외 유형이 들어갑니다.
# ExceptionType2 예외가 발생했을 때 실행될 코드
# 추가적인 except 블록을 계속 추가할 수 있습니다.
else: # 필수 x
# try 블록에서 예외가 발생하지 않았을 때 실행될 코드
finally: # 필수 x
# 예외 발생 여부와 관계없이 항상 실행될 코드
try:
raise KeyboardInterrupt # raise: 예외를 강제로 발생시키는 코드
except Exception:
print("Exception 잡힘")
except BaseException:
print("BaseException 잡힘")
👉 이때 except BaseException: 을 except:로 사용한다면 시스템을 정상적으로 종료해야하는 신호까지 모두 막아버릴 수 있으므로 생략해선 안된다.
raise
raise는 파이썬에서 의도적으로 예외를 발생시키거나(throw), 현재 발생한 예외를 다시 전달(re-raise)하기 위해 사용하는 키워드이다. 이를 통해 잘못된 입력이나 비정상적인 상태를 명확하게 알리고, 호출한 쪽에서 적절히 처리하도록 흐름을 제어할 수 있다.
파이썬 주요 예외 타입 정리

try:
data = [10, 20, 30, 40, 50]
# print(data[5]) -> IndexError
# print(int('안녕')) -> ValueError
# print(5 / 0) -> ZeroDivisionError
except IndexError:
print('인덱스 오류')
except ValueError:
print('입력 오류')
except ZeroDivisionError:
print('0으로 나눌 수 없음')
except Exception:
print('예외 발생!')
else:
print('에러가 발생하지 않은 정상적인 프로그램')
finally:
print('에러에 관계없이 무조건 실행되는 문장')
print('프로그램을 종료합니다')
예외 객체 내부 구조
Exception 객체
├── args → 에러 메시지
├── __str__() → 사용자용 메시지
├── __repr__() → 개발자용 표현
├── __class__ → 에러 타입
└── __traceback__ → 에러 발생 위치 정보
1. args (에러 메세지 튜플)
예외 객체를 생성할 때 전달한 인자(Arguments)들이 담기는 튜플이다. 보통은 에러의 원인을 설명하는 문자열 메세지가 들어간다.
2. __str__() (사용자용 메세지)
사용자가 읽기 좋은 형태로 에러 메세지를 문자열로 반환해 주는 메서드.
3. __repr__() (개발자용 공식 표현)
이 객체가 어떤 클래스의 객체이고, 어떤 인자를 가지고 생성되었는지 명확하게 보여주는 개발자용 문자열. 주로 디버깅이나 로그(Log)를 남길 때 유용하다.
4. __class__ (에러 타입)
이 예외 객체가 정확히 어떤 에러 클래스(타입)에 속하는지 알려준다. 에러의 종류에 따라 로그를 다르게 남기거나 분기 처리를 하고 싶을 때 활용한다.
5. __traceback__ (에러 발생 위치 및 경로)
코드가 실행되다가 정확히 몇 번째 줄에서, 어떤 함수들을 거쳐 에러가 났는지에 대한 발자취(Traceback 객체)를 담고 있다. 그냥 출력하면 객체 주소만 보이기 때문에, 파이썬의 내장 모듈인 traceback과 함께 사용하면 리포트 형태로 출력된다.
import traceback
try:
int("abc")
except Exception as e: # as는 발생한 예외 객체를 변수로 받아서, 그 안에 담긴 정보를 활용하기 위함.
print("에러 메시지:", e)
print("에러 타입:", type(e))
print("args:", e.args)
print(e.__str__())
print(e.__repr__())
print(e.__class__)
print(e.__traceback__)
traceback.print_tb(e.__traceback__)
# 에러 메시지: invalid literal for int() with base 10: 'abc'
# 에러 타입: <class 'ValueError'>
# args: ("invalid literal for int() with base 10: 'abc'",)
# invalid literal for int() with base 10: 'abc'
# ValueError("invalid literal for int() with base 10: 'abc'")
# <class 'ValueError'>
# <traceback object at 0x000001FD7D205840>
# File "C:\Users\Administrator\AppData\Local\Temp\ipykernel_324\1305646378.py", line 4, in <module>
# int("abc")
def func1():
func2()
# try:
# func2()
# except TypeError:
# print('타입이 올바르지 않습니다')
def func2():
func3()
# try:
# func3()
# except TypeError:
# print('타입이 올바르지 않습니다')
def func3():
print('%d' % '문자열')
# try:
# print('%d' % '문자열')
# except TypeError:
# print('타입이 올바르지 않습니다')
# func1()
try:
func1()
except TypeError:
print('타입이 올바르지 않습니다')
👉 func3에서 에러가 발생하면 이를 해결할 try-except가 있을 때까지 func3 → func2 → func1 → 호출부 순서로 에러를 위로 전파한다. 따라서 어느 부분에서 예외처리를 해도 상관이 없다.
'Python' 카테고리의 다른 글
| 모듈 (0) | 2026.06.01 |
|---|---|
| 매직 메서드 (0) | 2026.05.29 |
| 객체지향 프로그램 4대 패러다임 (1) | 2026.05.28 |
| 객체지향 프로그래밍 (0) | 2026.05.28 |
| 사용자 정의 함수 part2 (0) | 2026.05.28 |