프로그래밍/Python

파이썬 예외 처리 완벽 가이드: 프로그램 안정성을 위한 필수 개념

shimdh 2025. 2. 25. 13:36
728x90

소프트웨어 개발을 하다 보면 예상치 못한 오류가 발생할 수 있습니다. 예기치 않은 오류가 발생하면 프로그램이 강제로 종료될 수 있으며, 이는 사용자 경험을 해치는 주요 요인이 됩니다. 예외 처리(Exception Handling) 는 이러한 오류를 효과적으로 관리하여 프로그램이 보다 안정적으로 실행되도록 하는 핵심 기술입니다.

이번 글에서는 파이썬의 예외 처리 개념을 깊이 있게 살펴보고, 실제 개발 환경에서 활용할 수 있는 실용적인 예제와 모범 사례를 공유하겠습니다.


1. 예외란 무엇인가?

1.1 예외(Exception)와 오류(Error)의 차이

프로그래밍에서 오류(Error) 는 심각한 문제가 발생하여 프로그램이 더 이상 실행될 수 없는 상황을 의미합니다. 반면, 예외(Exception) 는 실행 중 발생할 수 있는 예측 가능한 문제로, 적절한 처리를 통해 정상적으로 프로그램을 계속 실행할 수 있습니다.

예를 들어, 0으로 나누기(ZeroDivisionError), 잘못된 데이터 타입 사용(TypeError) 등의 문제는 예외로 간주되며, 적절한 처리를 하면 프로그램이 종료되지 않고 계속 실행될 수 있습니다.

1.2 예외가 발생하는 일반적인 사례

  • 잘못된 연산 수행: 0으로 나누기 (ZeroDivisionError)
  • 부적절한 데이터 타입 사용: 문자열을 정수로 변환 시 오류 (TypeError, ValueError)
  • 파일을 찾을 수 없음: 존재하지 않는 파일을 열려고 할 때 (FileNotFoundError)
  • 리스트의 범위를 초과한 인덱스 접근 (IndexError)
  • 딕셔너리에서 존재하지 않는 키를 참조 (KeyError)

2. 파이썬의 기본 예외 처리 문법

파이썬에서는 try, except, else, finally 블록을 사용하여 예외를 처리합니다.

try:
    # 예외가 발생할 가능성이 있는 코드
except 예외_타입:
    # 예외 발생 시 실행할 코드
else:
    # 예외가 발생하지 않았을 경우 실행할 코드
finally:
    # 예외 발생 여부와 관계없이 항상 실행되는 코드

2.1 예외 처리 예제: 나눗셈 연산

다음은 두 개의 숫자를 나누는 프로그램으로, 0으로 나누는 경우와 잘못된 입력을 처리하는 예제입니다.

def divide_numbers(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        return "오류: 0으로 나눌 수 없습니다."
    except TypeError:
        return "오류: 숫자를 입력해야 합니다."
    else:
        return f"결과: {result}"
    finally:
        print("연산 완료.")

# 테스트
print(divide_numbers(10, 2))   # 정상 출력
print(divide_numbers(10, 0))   # ZeroDivisionError 처리
print(divide_numbers(10, 'a')) # TypeError 처리

3. 예외의 종류와 예제

3.1 주요 내장 예외 (Built-in Exceptions)

파이썬에서는 여러 종류의 예외를 기본적으로 제공합니다. 대표적인 예외와 예제는 다음과 같습니다.

3.1.1 ZeroDivisionError: 0으로 나누기 시도

try:
    print(10 / 0)
except ZeroDivisionError:
    print("오류: 0으로 나눌 수 없습니다.")

3.1.2 TypeError: 잘못된 데이터 타입 사용

try:
    print("10" + 5)
except TypeError:
    print("오류: 문자열과 숫자를 더할 수 없습니다.")

3.1.3 ValueError: 잘못된 값 입력

try:
    num = int("abc")  # 문자열을 정수로 변환 시도
except ValueError:
    print("오류: 숫자가 아닌 값을 입력했습니다.")

3.1.4 FileNotFoundError: 존재하지 않는 파일 열기

try:
    with open("non_existent_file.txt", "r") as file:
        content = file.read()
except FileNotFoundError:
    print("오류: 파일을 찾을 수 없습니다.")

4. 사용자 정의 예외 만들기

기본 예외만으로 충분하지 않을 경우, 개발자는 직접 새로운 예외를 정의하여 사용할 수 있습니다.

4.1 사용자 정의 예외 클래스 생성

class NegativeNumberError(Exception):
    """음수를 입력하면 발생하는 예외"""
    pass

def sqrt(num):
    if num < 0:
        raise NegativeNumberError("오류: 음수의 제곱근은 계산할 수 없습니다.")
    return num ** 0.5

try:
    print(sqrt(-9))
except NegativeNumberError as e:
    print(e)

5. 여러 개의 예외 처리하기

하나의 except 블록에서 여러 개의 예외를 처리할 수도 있습니다.

def convert_to_int(value):
    try:
        return int(value)
    except (TypeError, ValueError):
        return "오류: 올바른 숫자 값을 입력하세요."

print(convert_to_int("123"))  # 123
print(convert_to_int("abc"))  # 오류 메시지 출력
print(convert_to_int(None))   # 오류 메시지 출력

6. 예외 발생시키기 (raise 문 사용)

개발자는 raise 키워드를 사용하여 특정 상황에서 예외를 강제로 발생시킬 수 있습니다.

def check_age(age):
    if age < 18:
        raise ValueError("오류: 18세 이상만 등록 가능합니다.")
    return "등록이 완료되었습니다."

try:
    print(check_age(16))
except ValueError as e:
    print(e)

7. 결론: 예외 처리를 통해 프로그램 안정성 강화

예외 처리는 프로그램이 예상치 못한 오류 상황에서도 안정적으로 실행될 수 있도록 돕는 필수 기술입니다. 예외를 적절히 처리하면 다음과 같은 장점이 있습니다.

✅ 프로그램의 안정성이 증가
✅ 사용자 경험(UX) 향상
✅ 예외 발생 시 빠른 오류 분석 가능

파이썬의 기본 예외와 사용자 정의 예외를 적절히 활용하여 보다 안전하고 신뢰할 수 있는 프로그램을 개발해 보세요!

728x90