프로그래밍/Python

예외 처리: 안정적인 프로그램을 위한 예외의 종류와 관리 방법

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

소프트웨어 개발에서 예외 처리(Exception Handling) 는 필수적인 개념입니다. 예외 처리를 통해 프로그램이 비정상적으로 종료되는 것을 방지하고, 오류가 발생하더라도 원활한 실행이 가능하도록 만들 수 있습니다.

특히 파이썬(Python) 에서는 다양한 내장 예외(Built-in Exception) 가 제공되며, 이를 이해하고 적절히 활용하는 것이 안정적이고 유지보수하기 쉬운 코드 작성의 핵심 요소입니다.

또한, 기본적으로 제공되는 예외 외에도, 사용자 정의 예외(Custom Exception) 를 활용하면 특정 상황에서 보다 직관적인 오류 메시지를 제공하고, 코드의 가독성을 향상시킬 수 있습니다.

이번 글에서는 자주 발생하는 예외의 종류, 이를 처리하는 방법, 그리고 예외를 효과적으로 관리하는 베스트 프랙티스까지 깊이 있게 다뤄보겠습니다.


🔹 1. 기본적인 예외 유형: 프로그램에서 자주 발생하는 오류들

파이썬을 사용하다 보면 다양한 유형의 예외를 만나게 됩니다. 그중 가장 흔하게 발생하는 예외를 살펴보고, 해결 방법을 알아보겠습니다.


📌 1.1 SyntaxError (문법 오류)

문법적으로 잘못된 코드가 실행될 때 발생하는 오류입니다.
괄호가 닫히지 않거나, 콜론(:)이 빠졌거나, 잘못된 예약어가 사용될 경우 나타납니다.

  • 예제:

      print("Hello World"  # 닫히지 않은 괄호
  • 해결 방법:
    ✅ 괄호, 따옴표, 콜론 등의 문법 요소가 정확히 닫혔는지 확인
    ✅ 코드의 문법이 올바른지 VS Code, PyCharm 등의 코드 분석 기능 활용


📌 1.2 TypeError (잘못된 타입 연산)

호환되지 않는 데이터 타입 간의 연산을 수행할 때 발생하는 오류입니다.

  • 예제:

      result = "10" + 5  # 문자열과 정수를 더하려고 시도
  • 해결 방법:
    int() 또는 str()을 사용하여 타입을 변환(casting)

      result = int("10") + 5  # 정상 실행됨

📌 1.3 ValueError (잘못된 값)

함수나 연산자가 적절한 데이터 타입을 받았지만, 값이 유효하지 않을 때 발생하는 오류입니다.

  • 예제:

      int_value = int("abc")  # 문자열 'abc'는 정수로 변환 불가능
  • 해결 방법:
    try-except 문을 사용하여 예외를 처리

      try:
          int_value = int("abc")
      except ValueError:
          print("올바른 숫자를 입력하세요.")

📌 1.4 IndexError (리스트 범위를 초과하는 접근)

리스트, 튜플 등의 데이터에서 존재하지 않는 인덱스를 참조할 때 발생하는 오류입니다.

  • 예제:

      my_list = [1, 2, 3]
      print(my_list[5])  # 존재하지 않는 인덱스
  • 해결 방법:
    len()을 사용하여 인덱스 범위를 초과하지 않도록 확인

      if len(my_list) > 5:
          print(my_list[5])
      else:
          print("유효한 인덱스를 입력하세요.")

📌 1.5 KeyError (존재하지 않는 키 사용)

딕셔너리에서 존재하지 않는 키를 참조할 때 발생하는 오류입니다.

  • 예제:

      my_dict = {"name": "Alice"}
      print(my_dict["age"])  # 'age' 키가 없으므로 KeyError 발생
  • 해결 방법:
    .get() 메서드를 사용하여 안전한 값 반환

      print(my_dict.get("age", "키가 존재하지 않습니다."))

🔹 2. 사용자 정의 예외: 특정 상황을 보다 명확하게 처리

기본 제공되는 예외만으로는 모든 오류를 처리하기 어렵습니다.
이때 사용자 정의 예외(Custom Exception) 를 만들어 특정 상황에서 더 명확한 오류 처리가 가능합니다.


📌 2.1 사용자 정의 예외 생성

  • 예제:

      class NegativeValueError(Exception):
          """음수 값이 입력되었을 때 발생하는 예외"""
          pass
    
      def check_value(value):
          if value < 0:
              raise NegativeValueError("값은 음수가 될 수 없습니다.")
    
      try:
          check_value(-1)
      except NegativeValueError as e:
          print(e)  

✅ 사용자 정의 예외를 활용하면 오류의 의미가 더욱 명확해지고, 디버깅이 쉬워집니다.


🔹 3. 예외 처리의 베스트 프랙티스

📌 3.1 여러 개의 예외 처리

여러 개의 예외가 발생할 가능성이 있는 경우, 다중 예외 처리를 사용하면 프로그램의 안정성을 높일 수 있습니다.

  • 예제:
      try:
          x = int("abc")  # ValueError 발생 가능
          y = 10 / 0      # ZeroDivisionError 발생 가능
      except ValueError:
          print("올바른 숫자를 입력하세요.")
      except ZeroDivisionError:
          print("0으로 나눌 수 없습니다.")
      except Exception as e:
          print(f"예상치 못한 오류 발생: {e}")

📌 3.2 finally 블록 활용

예외 발생 여부와 관계없이 항상 실행되어야 하는 코드가 있을 때 finally 블록을 사용합니다.

  • 예제:
      try:
          file = open("data.txt", "r")
          content = file.read()
      except FileNotFoundError:
          print("파일을 찾을 수 없습니다.")
      finally:
          file.close()  # 파일을 항상 닫음

finally를 사용하면 자원(파일, 데이터베이스 연결 등)을 안전하게 정리할 수 있습니다.


🎯 결론: 예외 처리로 안정적인 코드 작성

🔹 예외 처리의 핵심 요약

다양한 예외를 이해하고 적절한 방식으로 처리해야 함
사용자 정의 예외를 활용하여 보다 직관적인 오류 메시지를 제공
다중 예외 처리를 통해 프로그램의 안정성을 높임
finally 블록을 활용하여 자원을 안전하게 정리

예외 처리는 견고하고 신뢰성 있는 소프트웨어를 개발하는 데 필수적인 요소입니다.
이번 글을 통해 예외의 종류와 적절한 대응 방식을 익혀, 더 안정적인 프로그램을 작성해 보세요! 🚀

728x90