[Python] 예외처리 - try/except, raise, 추상클래스, 사용자 정의 예외
by 우와한개발자
1. 예외 클래스
- 자바는 예외 클래스명이 Exception으로 끝나는 경우가 많고, 파이썬은 Error로 끝나는 경우가 많음 (예: ValueError, TypeError, IndexError)
- 주요 예외 클래스
BaseException ← 모든 예외의 최상위 클래스
├── SystemExit ← sys.exit() 호출 시
├── KeyboardInterrupt ← Ctrl+C 입력 시
└── Exception ← 일반 예외의 최상위 (우리가 주로 다루는 것)
├── ArithmeticError
│ └── ZeroDivisionError ← 0으로 나눌 때
├── LookupError
│ ├── IndexError ← 리스트 인덱스 초과
│ └── KeyError ← 딕셔너리 키 없음
├── OSError
│ ├── FileNotFoundError ← 파일 없음
│ └── PermissionError ← 권한 없음
├── TypeError ← 타입 오류
├── ValueError ← 값 오류
├── NameError ← 변수명 없음
├── AttributeError ← 속성 없음
├── ImportError ← 모듈 import 실패
│ └── ModuleNotFoundError
└── RuntimeError
└── NotImplementedError ← 추상메서드 미구현
2. 예외처리 : try ~ except
1) 기본 구조
try:
# 예외가 발생할 수 있는 코드
result = 10 / 0
except ZeroDivisionError:
# 예외 발생 시 실행
print("0으로 나눌 수 없습니다")
2) 예외별로 처리
- 발생 가능한 예외가 여러 개일 경우 자식 클래스부터 작성 (부모가 먼저면 자식 예외가 걸리지 않음)
try:
value = int(input("숫자 입력: "))
result = 10 / value
except ValueError: # 자식 먼저
print("숫자가 아닙니다")
except ZeroDivisionError: # 자식 먼저
print("0으로 나눌 수 없습니다")
except Exception: # 부모는 마지막
print("알 수 없는 예외")
3) 다중 예외 처리
- 여러 예외를 하나의 except에서 처리할 때 튜플로 묶음
try:
value = int(input("숫자 입력: "))
result = 10 / value
except (ValueError, ZeroDivisionError):
print("잘못된 입력입니다")
4) else
- 예외가 발생하지 않았을 때 실행
- try 안에 써도 되지만 정상 실행 코드와 예외 처리 코드를 분리해 직관적으로 구분하기 위해 사용
try:
result = 10 / 2
except ZeroDivisionError:
print("0으로 나눌 수 없습니다")
else:
print(f"결과 : {result}") # 예외 없을 때만 실행
5) 예외 인수
- 예외 객체를 as 별칭으로 받아 예외 관련 메시지나 값을 확인할 수 있음
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"예외 발생 : {e}") # division by zero
6) finally
- 예외 발생 여부와 관계없이 항상 실행
- 주로 리소스 해제(파일 닫기, DB 연결 종료 등)에 사용
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"예외 발생 : {e}")
finally:
print("항상 실행됨") # 예외 발생해도 실행
⚠️ with문
- finally에서 리소스 해제 코드를 반복 작성하는 불편함을 해소
- with 블록을 벗어나면 자동으로 리소스 해제 (close() 자동 호출)
- 파일, DB 연결 등에 주로 사용
# 기존 방식 — finally로 직접 닫아야 함 try: f = open('file.txt', 'r') data = f.read() finally: f.close() # with 방식 — 자동으로 닫힘 with open('file.txt', 'r') as f: data = f.read() # 블록 벗어나면 f.close() 자동 실행
3. 예외 발생 : raise
- 예외를 강제로 발생시킴
- 주로 if문 안에서 조건에 따라 사용
def set_age(age):
if age < 0:
raise ValueError("나이는 0 이상이어야 합니다")
return age
try:
set_age(-1)
except ValueError as e:
print(e) # 나이는 0 이상이어야 합니다
4. 추상클래스와 추상메서드
1) 예외 발생을 통한 구현
- 파이썬은 추상클래스 또는 추상메서드를 위한 키워드가 없음
- 생성자나 메서드에 raise를 이용해 직접 구현 강제
class Shape:
def area(self):
raise NotImplementedError("area() 메서드를 구현해야 합니다")
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
c = Circle(5)
print(c.area()) # 78.5
2) abc모듈 사용한 구현
- abc 모듈의 @abstractmethod 데코레이터 이용
- 추상메서드를 구현하지 않으면 객체 생성 자체가 불가능
from abc import ABC, abstractmethod
class Shape(ABC): # ABC 상속
@abstractmethod
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self): # 반드시 구현해야 함
return 3.14 * self.radius ** 2
# Shape() # ❌ TypeError: 추상클래스는 객체 생성 불가
c = Circle(5)
print(c.area()) # 78.5
5. 사용자 정의 예외
- Exception 클래스 또는 그 하위 클래스를 상속받아 생성
class ZeroLengthError(Exception):
def __init__(self):
super().__init__('사용자 정의 예외 : 길이가 0입니다.')
def check_length(data):
if len(data) == 0:
raise ZeroLengthError()
try:
check_length([])
except ZeroLengthError as e:
print(e) # 사용자 정의 예외 : 길이가 0입니다.
'언어 > Python' 카테고리의 다른 글
| [Python] CSV 파일 읽고 쓰기 - csv.reader, DictReader, DictWriter (0) | 2026.04.19 |
|---|---|
| [Python] 파일 읽고 쓰기 - %%writefile, open(), read/write, 피클(pickle) (0) | 2026.04.19 |
| [Python] 클래스 상속 - super(), 메서드 재정의, name mangling(_클래스명__변수명) (0) | 2026.04.19 |
| [Python] 클래스 메서드, 정적 메서드, 생성자와 소멸자 - @classmethod, @staticmethod, __init__ (0) | 2026.04.19 |
| [Python] 클래스(class)와 객체(object) - 구조, 네임스페이스, self (0) | 2026.04.19 |
블로그의 정보
우와한개발자 님의 블로그
우와한개발자