본문 바로가기
파이썬/기초 학습

Day 10: 예외 처리 추가 학습

by CBROJIN 2025. 8. 5.

1) 학습 요약표

개념 설명 내용
예외 처리 개념 실행 중 발생할 수 있는 오류 상황을 미리 고려하여 프로그램의 중단 없이 처리하는 기법
try-except 구조 예외가 발생할 수 있는 코드를 try 블록에 작성하고, 오류 발생 시 처리할 코드를 except에 작성
else/finally 사용 예외가 발생하지 않았을 때의 처리(else)나, 무조건 실행되는 코드(finally) 작성
raise 문 사용자가 직접 오류를 발생시킬 수 있는 구문 (강제 오류 발생 시 사용)
 

2) 이론 설명

1. 예외(Exception) 처리란?

  • 예외(Exception)는 프로그램 실행 중 오류가 발생하는 모든 상황을 의미합니다.
  • 예외 처리는 이러한 오류 상황에서도 프로그램을 강제 종료하지 않고, 정상 흐름을 유지할 수 있도록 처리하는 방식입니다.
  • 네트워크 장비 상태 수집이나 로그 분석 자동화 프로그램에서도 연결 실패, 포맷 오류 등의 예외를 처리하지 않으면 전체 자동화가 중단되므로, 반드시 필요한 개념입니다.
  • Python에서는 try, except, else, finally, raise 문을 통해 예외 처리 흐름을 세밀하게 제어할 수 있습니다.
  • 프로그램 실행 도중 발생할 수 있는 오류를 예측하고, 해당 오류를 안전하게 처리하는 방식입니다.
  • 예외 처리를 하지 않으면 오류 발생 시 프로그램이 강제 종료됩니다.
  • 예외 처리는 try ~ except 문을 중심으로 다양한 방식으로 사용할 수 있습니다.

2. 주요 예외 종류

  • Python에서 자주 발생하는 예외는 어떤 코드 상황에서 발생하는지 명확히 이해해야 문제를 빠르게 해결할 수 있습니다.
예외 유형 발생 조건 및 설명
SyntaxError 잘못된 문법(예: 괄호, 콜론 누락 등) 사용 시 발생. 프로그램 실행 전에 발생함.
IndentationError 들여쓰기가 잘못되었을 때 발생. Python은 들여쓰기를 통해 블록을 구분하기 때문에 중요.
NameError 존재하지 않는 변수나 객체에 접근했을 때 발생. 오타나 선언 누락 등으로 자주 발생함.
TypeError 잘못된 타입 간 연산 또는 호출 시 발생. 예: 문자열 + 정수 연산, 함수 호출 대상이 아닌 객체 호출 등
ValueError 자료형은 맞지만 값이 적절하지 않을 때 발생. 예: int("abc"), 리스트에서 없는 값을 remove() 할 때 등
ZeroDivisionError 숫자를 0으로 나누려 할 때 발생. 나눗셈, 나머지 연산에서 해당.
FileNotFoundError open() 등으로 파일을 열 때, 해당 파일이 존재하지 않을 경우 발생.
IndexError 시퀀스 자료형(리스트 등)에서 존재하지 않는 인덱스를 참조할 때 발생.
KeyError 딕셔너리에 존재하지 않는 키를 참조할 때 발생. dict['없는키'] 사용 시 발생함.

3. try-except 기본 구조

  • try 블록에 예외가 발생할 수 있는 코드를 작성하고,
  • except 블록에서 해당 예외를 잡아 처리합니다.
  • as 키워드를 통해 예외 메시지를 변수로 받아올 수 있습니다.
  • 기본적인 예외 처리는 아래와 같은 구조를 따릅니다:
try:
    실행할 코드
except 예외종류 as 변수:
    예외 발생 시 처리할 코드

예제 1: ZeroDivisionError 처리

  • 숫자를 0으로 나누려고 하면 ZeroDivisionError가 발생합니다.
  • 이를 사전에 처리하여 프로그램이 멈추지 않도록 할 수 있습니다.
num = int(input("숫자를 입력하세요: "))
try:
    print(100 / num)
except ZeroDivisionError as e:
    print("0으로는 나눌 수 없습니다.", e)


try:
    result = 10 / 0
except ZeroDivisionError as e:
    print("예외 발생:", e)

예제 2: try ~ else

  • else 블록은 예외가 발생하지 않았을 때만 실행됩니다.
  • 예외 없이 정상적으로 실행되었음을 구분하고자 할 때 사용합니다.
port = input("포트 번호를 입력하세요: ")
try:
    port_num = int(port)
except ValueError:
    print("숫자만 입력 가능합니다.")
else:
    print(f"{port_num}번 포트가 입력되었습니다.")


try:
    result = 10 / 2
except ZeroDivisionError as e:
    print("오류 발생:", e)
else:
    print("정상 처리 결과:", result)

예제 3: try ~ finally

  • finally 블록은 예외 발생 여부와 관계없이 항상 실행되는 영역입니다.
  • 예를 들어, 파일을 열고 나서 무조건 닫아야 할 경우, 또는 네트워크 세션 종료 등 자원 해제를 위한 블록입니다.
try:
    f = open("config.txt", "r")
    print(f.read())
except FileNotFoundError:
    print("파일이 존재하지 않습니다.")
finally:
    print("파일 읽기 시도 완료")


try:
    result = 10 / 0
except ZeroDivisionError:
    print("0으로 나눌 수 없습니다.")
finally:
    print("ZeroDivisionError 확인 완료")

 

예제 4: 예외 무시하기 (pass 사용)

  • 예외가 발생했을 때 아무 조치도 하지 않고 그냥 넘어가야 할 경우 pass를 사용할 수 있습니다.
  • 하지만 중요한 예외까지 무시하면 문제가 발생할 수 있으므로 주의해서 사용합니다.
user_input = input("숫자 입력: ")
try:
    print(int(user_input))
except ValueError:
    pass  # 형식 오류 무시하고 넘어감
print("프로그램 계속 진행 중...")


try:
    10 / 0
except ZeroDivisionError:
    pass  # 아무런 처리 없이 넘어감

 

예제 5: 예외 강제로 발생시키기 (raise)

  • raise 문을 사용하면 사용자가 직접 예외를 발생시킬 수 있습니다.
  • 유효성 검사에서 조건이 맞지 않을 때 명확한 에러 메시지를 주고 종료하기 위해 많이 사용합니다.
device_name = ""

try:
    if not device_name:
        raise ValueError("장비 이름이 비어 있습니다.")
except ValueError as e:
    print("오류 발생:", e)


try:
    raise NameError("사용자 정의 NameError")
except NameError as e:
    print("직접 발생시킨 오류:", e)

 

3) 종합 실습

과제 1: 사용자 입력 오류 처리기 작성

문제 설명 : 사용자로부터 숫자 2개를 입력받아 나눗셈을 수행하는 프로그램을 작성하세요.

  • 두 입력값 중 하나라도 숫자가 아닌 경우 ValueError를 처리합니다.
  • 나눗셈 시 0으로 나누는 경우는 ZeroDivisionError로 처리합니다.
  • 예외가 없을 경우 정상 결과를 출력하며, 마지막에는 항상 "프로그램 종료"를 출력하도록 finally 블록을 사용합니다.

과제 2: 장비 딕셔너리 키 접근 오류 처리

문제 설명 : 장비 상태를 담은 딕셔너리에서 사용자 입력에 따라 장비 상태를 출력하세요.

  • 존재하지 않는 장비 이름을 입력하면 KeyError로 처리하여 안내 메시지를 출력합니다.

 

과제 3: 포트 번호 검사기 (raise 사용)

문제 설명 : 사용자에게 포트 번호를 입력받고 유효한 범위(1~65535)인지 검사합니다.

  • 범위를 벗어난 경우 raise ValueError로 명시적인 오류를 발생시키고 메시지를 출력하세요.