python 10장. 예외 처리

Hyuna·2024년 8월 2일

Python 기본

목록 보기
10/17
post-thumbnail

프로그램을 실행하다 보면 종종 알 수 없는 오류가 발생하곤 한다
이는 프로그램 실행을 멈추기 때문에 오류 코드에 대응해 프로그램 실행이 멈추는 것을 최소화해야 한다




우선 발생하는 오류에 대해 알아보자

1. 오류

  • 프로그래밍 오류
    문법 오류
    논리 오류: 문제 해결 방법을 잘못 지정
    실행 오류: 문법적/논리적 문제가 없는데 오류 발생
    ex) int()명렬에 실수 형태 문자열 전달

  • 문법 오류(SyntaxError)
    프로그래밍 언어를 잘못 사용해서 발생
    파이썬이 어디서 오류가 발생했는지 알려준다

📌 오류 TOP8

오류 종류설명
ValueError인자로 다른 자료형의 값을 전달
IndexError자료구조에서 인덱스의 범위를 벗어남
NameError값이 저장되지 않은 변수가 사용됨
UnicodeDecodeError파일이 저장된 인코딩 방식과 지정된 인코딩 방식이 다름
TypeError허용되지 않은 자료형 사용
FileNotFoundError파일이 없음
ZeroDivisionError0으로 나눔
SyntaxError잘못된 문법 사용



2. 예외 처리

프로그램을 실행시키면서 발생할 수 있는 오류 상황을 예외 처리

      try:
           오류를 발생 시킬 수 있는 코드
      except:
          오류가 발생했을 때 실행시킬 코드

   
      try:
         s = input("정수를 입력하세요: ")
         n = int(s)
         print("사용자가 입력한 정수:", n)
      except:
         print(f"정수로 변환할 수 없습니다. 입력값 {s}")
     print("프로그램 종료")   
     
>> 3.5
>> 정수로 변환할 수 없습니다. 입력값 3.5
>> 프로그램 종료

📌 raise 예외

  • 예외 발생시 "에러메시지" 출력
try:
    x = int(input("3의 배수 입력: "))
    if x% 3 != 0:
        raise Exception("3의 배수 아님")
    print(x)
except Exception as e:
    print("에러 발생 : ", e)
print("End of the program")


>> 3의 배수 입력: 7
>> 에러 발생: 3의 배수 아님
>> End of the program
  • re-raise: 현재 예외를 다시 발생
def three_div():
    try: 
        
    
        x = int(input("3의 배수 입력: "))
        if x% 3 != 0:
            raise Exception("3의 배수 아님")
            print(x)
    except Exception as e:
        print("에러 발생 : ", e)
        raise
try:
    three_div()
except Exception as e:
    print("코드 에러 발생: ", e)
    
>> 3의 배수 입력: 10
>> 에러 발생: 3의 배수 아님
>> 코드 에러 발생: 3의 배수 아님

📌 pass문

  • 오류가 발생했을 때, 오류를 처리하지 않고 프로그램 실행을 지속
try:
    print(3 / 0) # 오류 발생
except ZeroDivisionError:
    pass 
print("오류가 발생함에도 여기까지 출력됨")

>> 오류가 발생함에도 여기까지 출력됨



def print_exception_info():
    
    try:
        num = int(input("숫자를 입력하세요: "))
        result = 100 / num
        print("결과:", result)
    except Exception as e:
        print(f"오류: {type(e).__name__}, 설명: {e}")
# 함수 호출
print_exception_info()

>> 숫자를 입력하세요: hi
>> 오류: ValueError, 설명: invalid literal for int() with base 10: 'hi'

📌 finally 블록

  • 예외 발생 여부와 상관없이 꼭 실행해야 하는 코드 블록
def read_file_with_finally():
   try:
       
       file = open("output.txt", "r")
       print(file.read())
   except FileNotFoundError:
       print("오류: 파일을 찾을 수 없습니다.")
   finally:
       file.close()
       print("파일이 닫혔습니다.")

read_file_with_finally()



💡 사용자로부터 파일 이름을 입력받아 파일을 열고 내용을 읽는 ‘예외 체인' 프로그램을 작성해보자

>> 파일을 찾을 수 없는 경우, 사용자에게 더 친절한 메시지를 제공하면서 원래의 예외도 함꼐 출력하자
def exception_chaining():
    try:
        
        filename = input("파일 이름을 입력하세요: ")
        with open(filename, "r") as file:
            print(file.read())
    except FileNotFoundError as e:
        raise FileNotFoundError("파일을 열 수 없습니다. 파일 이름을 확인하세요.") from e


try:
    exception_chaining()
except FileNotFoundError as e:
    print(e)
    print("원래의 예외:", e.__cause__)
    

>> 파일 이름을 입력하세요: 2
>> 파일을 열 수 없습니다. 파일 이름을 확인하세요.
>> 원래의 예외: [Errno 2] No such file or directory: '2'


3. 예외 체이닝(Explicit Chaining)

📌 context

  • 예외 처리중 다른 예외가 발생했을 때 원래 예외를 참조
  • 간단한 예외를 재발생 시키고자 할 때 사용
   __context__

📌 cause

  • 원본예외를 새로 발생한 예외 'cause'에 저장
  • 원래 예외를 명확하게 지정하고자 할 때 사용
   __cause__

0개의 댓글