[2026] Python 예외 처리 | try-except, raise, 커스텀 예외 완벽 정리
이 글의 핵심
Python 예외 처리: try-except, raise, 커스텀 예외 기본 예외 처리·try-except-else-finally.
들어가며
”에러를 우아하게 처리하기”
예외 처리는 프로그램의 안정성을 높이는 핵심 기술입니다.
실무 활용 사례: 데이터 분석, 웹 개발, 자동화 프로젝트에서 실제로 사용한 패턴과 코드를 바탕으로 정리했습니다. 초보자가 흔히 겪는 오류와 해결법을 포함합니다.
실무에서 느낀 Python의 매력
처음 Python을 배울 때는 “이게 정말 프로그래밍 언어인가?” 싶을 정도로 간결했습니다. C++에서 10줄로 작성하던 코드가 Python에서는 2~3줄로 끝나는 경우가 많았죠. 특히 데이터 분석 프로젝트를 진행하면서 Pandas와 NumPy의 강력함을 체감했습니다. 엑셀로 몇 시간 걸리던 작업이 Python 스크립트로는 몇 초 만에 끝나는 걸 보고 동료들이 놀라워했던 기억이 납니다. 하지만 처음부터 순탄하지만은 않았습니다. 들여쓰기 하나 잘못해서 몇 시간을 헤맨 적도 있고, 가상환경 설정이 꼬여서 프로젝트 전체를 다시 시작한 적도 있습니다. 이런 시행착오를 겪으며 깨달은 건, 환경 설정을 처음부터 제대로 하는 것이 얼마나 중요한지였습니다. 이 글에서는 제가 겪은 실수들을 바탕으로, 여러분이 같은 시행착오를 겪지 않도록 실전 팁을 담았습니다.
1. 기본 예외 처리
try-except
try 블록은 문제가 날 수 있는 줄을 안전 구역 안에 두는 것이고, except는 비상구로 빠져 나와 사용자에게 알맞은 메시지를 보여 주는 곳입니다. 0으로 나누기·잘못된 입력·없는 파일처럼 예상할 수 있는 실패마다 다른 except 절을 두면 원인 파악이 쉬워집니다.
다음은 python를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# 기본 형태
try:
result = 10 / 0
except ZeroDivisionError:
print("0으로 나눌 수 없습니다")
result = None
# 여러 예외 처리
try:
number = int(input("숫자 입력: "))
result = 10 / number
except ValueError:
print("숫자를 입력하세요")
except ZeroDivisionError:
print("0이 아닌 숫자를 입력하세요")
# 예외 객체 받기
try:
file = open('없는파일.txt', 'r')
except FileNotFoundError as e:
print(f"에러: {e}")
2. try-except-else-finally
전체 구조
다음은 python를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
try:
# 시도할 코드
file = open('data.txt', 'r')
content = file.read()
except FileNotFoundError:
# 예외 발생 시
print("파일이 없습니다")
else:
# 예외 없을 때만 실행
print(f"파일 읽기 성공: {len(content)}자")
finally:
# 항상 실행 (파일 닫기 등)
if 'file' in locals():
file.close()
print("작업 완료")
3. 예외 발생시키기 (raise)
기본 raise
아래 코드는 python를 사용한 구현 예제입니다. 함수를 통해 로직을 구현합니다, 에러 처리를 통해 안정성을 확보합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
def divide(a, b):
if b == 0:
raise ValueError("b는 0이 될 수 없습니다")
return a / b
try:
result = divide(10, 0)
except ValueError as e:
print(f"에러: {e}")
예외 재발생
아래 코드는 python를 사용한 구현 예제입니다. 함수를 통해 로직을 구현합니다, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
def process_data(data):
try:
result = int(data)
except ValueError:
print("데이터 변환 실패")
raise # 예외 재발생
try:
process_data("abc")
except ValueError:
print("상위에서 처리")
4. 커스텀 예외
사용자 정의 예외
다음은 python를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
class InsufficientBalanceError(Exception):
"""잔액 부족 예외"""
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"잔액 부족: {balance}원 (필요: {amount}원)")
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientBalanceError(self.balance, amount)
self.balance -= amount
return self.balance
# 사용
account = BankAccount("철수", 10000)
try:
account.withdraw(15000)
except InsufficientBalanceError as e:
print(e) # 잔액 부족: 10000원 (필요: 15000원)
print(f"현재 잔액: {e.balance}원")
5. 주요 예외 타입
자주 쓰는 예외
다음은 python를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# ValueError: 값이 잘못됨
try:
int("abc")
except ValueError:
print("숫자 변환 실패")
# TypeError: 타입이 잘못됨
try:
"hello" + 5
except TypeError:
print("타입 불일치")
# KeyError: 딕셔너리 키 없음
try:
data = {'name': '철수'}
print(data['age'])
except KeyError:
print("키가 없습니다")
# IndexError: 인덱스 범위 초과
try:
arr = [1, 2, 3]
print(arr[10])
except IndexError:
print("인덱스 초과")
# FileNotFoundError: 파일 없음
try:
open('없는파일.txt', 'r')
except FileNotFoundError:
print("파일이 없습니다")
6. 실전 예제
안전한 파일 처리
아래 코드는 python를 사용한 구현 예제입니다. 함수를 통해 로직을 구현합니다, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
def safe_read_json(filename):
"""JSON 파일 안전하게 읽기"""
try:
with open(filename, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f"{filename} 파일이 없습니다")
return {}
except json.JSONDecodeError as e:
print(f"JSON 파싱 에러: {e}")
return {}
except Exception as e:
print(f"예상치 못한 에러: {e}")
return {}
재시도 로직
다음은 python를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 함수를 통해 로직을 구현합니다, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
import time
def retry_operation(func, max_attempts=3):
"""실패 시 재시도"""
for attempt in range(max_attempts):
try:
return func()
except Exception as e:
print(f"시도 {attempt + 1} 실패: {e}")
if attempt < max_attempts - 1:
time.sleep(1)
else:
raise
# 사용
def unstable_operation():
import random
if random.random() < 0.7:
raise ConnectionError("연결 실패")
return "성공"
try:
result = retry_operation(unstable_operation)
print(result)
except Exception as e:
print(f"최종 실패: {e}")
예외를 골라 잡는 습관 (안전망)
try/except는 문제가 터졌을 때 프로그램 전체가 멈추지 않게 받쳐 주는 안전망입니다. Exception만 포괄적으로 잡으면 원인 추적이 어려우므로, 기대할 수 있는 예외 이름을 골라 처리하는 편이 유지보수에 유리합니다.
다음은 python를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# ✅ 구체적인 예외 처리
try:
value = int(user_input)
except ValueError:
print("숫자를 입력하세요")
# ❌ 너무 광범위한 예외 처리
try:
value = int(user_input)
except Exception: # 모든 예외를 잡음 (디버깅 어려움)
print("에러 발생")
# ✅ 예외 메시지 활용
try:
file = open('data.txt', 'r')
except FileNotFoundError as e:
print(f"파일 에러: {e}")
# ✅ 리소스 정리는 finally
try:
file = open('data.txt', 'r')
# 작업
finally:
file.close() # 항상 실행
정리
핵심 요약
- try-except: 예외 처리 기본
- finally: 항상 실행 (리소스 정리)
- raise: 예외 발생
- 커스텀 예외: Exception 상속
- 베스트 프랙티스: 구체적 예외, with 문