Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

나혼자 코딩

Python의 예외 처리: try, except, finally 그리고 예외 정의하기 본문

Python

Python의 예외 처리: try, except, finally 그리고 예외 정의하기

python2ai 2025. 3. 17. 12:37

Python을 활용한 개발에서는 예외(Exception) 처리가 필수적인 요소입니다. 예외 처리를 적절하게 활용하면 프로그램이 갑작스럽게 종료되는 것을 방지하고, 예상치 못한 오류를 보다 효율적으로 관리할 수 있습니다. 이번 글에서는 try-except 구조, finally 블록, 그리고 사용자 정의 예외를 다루며, 실무에서 활용할 수 있는 예외 처리 기법을 익혀보겠습니다.


1. 예외(Exception)란 무엇인가?

예외(Exception)는 프로그램 실행 중 발생하는 예상치 못한 상황을 의미합니다. 예외가 발생하면 프로그램이 즉시 종료될 수 있으므로, 이를 적절하게 처리하는 것이 중요합니다.

예외 처리는 단순히 오류를 회피하는 것이 아니라, 코드의 안정성을 높이고 예외적인 상황에서도 정상적인 흐름을 유지하도록 하는 핵심적인 기법입니다.

(1) 예외와 오류의 차이

오류(Error)와 예외(Exception)는 비슷한 개념처럼 보일 수 있지만, 실제로는 다릅니다. 오류는 보통 프로그램이 복구할 수 없는 심각한 문제이며, 예외는 적절한 처리를 통해 해결할 수 있는 문제입니다.

예를 들어, SyntaxError는 Python 코드가 문법적으로 잘못되었을 때 발생하는 오류이며, ZeroDivisionError는 0으로 나누기를 시도할 때 발생하는 예외입니다.

Python에서 발생하는 대표적인 오류와 예외는 다음과 같습니다:

구분 설명
오류(Error) 치명적인 문제로, 보통 해결할 수 없음 (예: 메모리 부족)
예외(Exception) 프로그래밍적으로 해결 가능한 오류 (예: 0으로 나누기)

(2) 예외 발생 예시

다음 코드에서는 0으로 나누는 연산을 수행하려고 할 때 ZeroDivisionError 예외가 발생합니다.

print(10 / 0)  # ZeroDivisionError 발생

이러한 예외를 처리하지 않으면 프로그램이 즉시 종료되므로, 예외 처리가 필요합니다.

또한, 사용자의 입력을 숫자로 변환하는 과정에서 발생할 수 있는 ValueError 예외를 살펴보겠습니다.

num = int("Python")  # ValueError 발생

이처럼 프로그램이 실행 중 예기치 않은 상황에 직면했을 때, 예외 처리를 활용하면 프로그램의 흐름을 보다 안정적으로 유지할 수 있습니다.


2. try-except 구조: 기본적인 예외 처리

예외 처리는 프로그램이 예상치 못한 상황에서도 원활하게 실행될 수 있도록 돕는 중요한 기법입니다. Python에서는 try-except 구조를 사용하여 예외를 감지하고 적절히 대응할 수 있습니다. 적절한 예외 처리는 프로그램의 신뢰성을 높이고, 유지보수를 더욱 용이하게 만듭니다.

(1) 기본 try-except 구조

try:
    x = 10 / 0  # 예외 발생
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다!")

출력:

0으로 나눌 수 없습니다!

(2) 여러 개의 예외 처리

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

try:
    num = int("Python")  # 문자열을 정수로 변환 시도
except ValueError:
    print("올바른 숫자를 입력하세요!")
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다!")

출력:

올바른 숫자를 입력하세요!

(3) 모든 예외 처리하기

모든 예외를 포괄적으로 처리하려면 Exception을 사용하면 됩니다.

try:
    print(10 / 0)
except Exception as e:
    print(f"예외 발생: {e}")

 

출력:

예외 발생: division by zero

⚠️ 주의: except Exception:을 남용하면 원인을 명확히 알 수 없으므로, 구체적인 예외를 명시하는 것이 권장됩니다.

 

2-1. try-except와 if-else의 차이점

예외 처리는 if-else 조건문을 사용하여 오류를 방지하는 것과 차이가 있습니다. if-else는 사전에 오류 발생 가능성을 검사하는 방식이며, try-except는 오류가 발생한 후 이를 처리하는 방식입니다.

if-else를 활용한 오류 방지

def divide(a, b):
    if b == 0:
        return "0으로 나눌 수 없습니다!"
    return a / b

print(divide(10, 2))  # 출력: 5.0
print(divide(10, 0))  # 출력: 0으로 나눌 수 없습니다!

위 코드에서는 if 문을 사용하여 0으로 나누는 경우를 사전에 방지합니다. 하지만 실수로 예외를 고려하지 못하면 프로그램이 종료될 수 있습니다.

try-except를 활용한 예외 처리

def divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return "0으로 나눌 수 없습니다!"

print(divide(10, 2))  # 출력: 5.0
print(divide(10, 0))  # 출력: 0으로 나눌 수 없습니다!

try-except를 사용하면 ZeroDivisionError가 발생하더라도 프로그램이 강제 종료되지 않고, 적절한 오류 메시지를 반환할 수 있습니다.

언제 if-else와 try-except를 사용해야 할까?

  • 오류를 사전에 방지할 수 있는 경우if-else 사용
  • 예외가 발생할 가능성이 있으며 이를 대비해야 하는 경우try-except 사용

예를 들어, 사용자의 입력 값을 검증하는 경우 if-else가 적절하지만, 네트워크 연결이나 파일 입출력 작업처럼 예측할 수 없는 상황에서는 try-except가 더 효과적입니다.


3. finally 블록 활용: 예외 발생 여부와 관계없이 실행되는 코드

finally 블록은 예외 발생 여부와 관계없이 항상 실행되는 코드를 포함하는 블록입니다. 주로 파일 닫기, 데이터베이스 연결 종료, 네트워크 연결 해제 등과 같은 리소스 정리를 보장하는 역할을 합니다.

finally 블록이 필요한 이유

일반적으로 예외가 발생하면 해당 코드 블록이 실행을 중단하고 except 블록으로 넘어가지만, 리소스 정리가 필요한 경우 예외 발생 여부와 관계없이 반드시 실행되어야 하는 코드가 있습니다. 예를 들어, 파일을 열어 데이터를 읽고 난 후에는 예외가 발생하든 그렇지 않든 반드시 파일을 닫아야 합니다.

try:
    file = open("data.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("파일을 찾을 수 없습니다!")
finally:
    print("파일을 닫습니다.")
    file.close()

 

출력:

파일을 찾을 수 없습니다!
파일을 닫습니다.

이처럼 finally 블록을 활용하면 자원 정리(Cleanup) 를 보장할 수 있습니다.


4. 사용자 정의 예외 (Custom Exception)

Python에서는 기본적으로 다양한 내장 예외를 제공하지만, 경우에 따라 특정한 비즈니스 로직이나 프로젝트의 요구사항에 맞춘 예외를 직접 정의해야 하는 경우가 있습니다. 사용자 정의 예외를 활용하면 보다 직관적이고 유지보수하기 쉬운 예외 처리 시스템을 구축할 수 있습니다.

(1) 사용자 정의 예외가 필요한 이유

  1. 표준 예외로 처리하기 어려운 특정한 로직이 있을 때
  2. 예외 메시지를 커스터마이징하고, 보다 의미 있는 오류 메시지를 제공할 때
  3. 특정한 예외를 잡아서 일괄적으로 처리하고 싶을 때 기본 제공 예외 외에도, 상황에 맞는 사용자 정의 예외를 만들어 활용할 수 있습니다.

(2) 사용자 정의 예외 생성하기

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

def check_positive(number):
    if number < 0:
        raise NegativeNumberError("음수는 허용되지 않습니다!")
    return number

try:
    check_positive(-5)
except NegativeNumberError as e:
    print(f"예외 발생: {e}")

 

출력:

예외 발생: 음수는 허용되지 않습니다!

사용자 정의 예외를 활용하면 보다 직관적인 예외 처리가 가능해집니다.


5. 예외 처리 베스트 프랙티스

효율적인 예외 처리는 단순히 try-except를 추가하는 것이 아니라, 코드의 안정성과 유지보수성을 고려한 전략적인 접근이 필요합니다. 잘못된 예외 처리는 오히려 버그를 숨기거나 디버깅을 어렵게 만들 수 있습니다. Python에서 예외 처리를 효과적으로 수행하기 위한 몇 가지 베스트 프랙티스를 소개합니다.

 

구체적인 예외를 명시하라 (except Exception: 사용 최소화)

필요한 경우만 예외를 처리하라 (불필요한 try-except 사용 금지)

finally 블록을 사용하여 리소스를 정리하라 (파일, 네트워크 연결 닫기)

사용자 정의 예외를 적극 활용하라 (보다 명확한 예외 처리 가능)


마무리

Python의 예외 처리는 코드의 안정성을 높이고, 예상치 못한 상황을 효율적으로 관리할 수 있도록 도와줍니다.

  • try-except 구문을 활용하여 예외 발생 시 프로그램이 종료되지 않도록 방지할 수 있습니다.
  • finally 블록을 사용하여 자원 정리를 보장할 수 있습니다.
  • 사용자 정의 예외를 만들어 특정한 상황에 맞는 예외 처리를 구현할 수 있습니다.

실제 프로젝트에서 예외 처리를 효과적으로 적용하여, 보다 신뢰할 수 있는 Python 코드를 작성해봅시다!