Python/Basics

25. 예외 처리

2024. 2. 3. 04:51

  • -

10.1 예외 처리란?

예외란, 간단히 오류다.

프로그램은 실행 중 오류가 발생하면, 종료된다. 이는 서비스에 제일 치명적인 문제다.

오류 발생이 예상되는 부분에, 오류로 인한 의도하지 않은 강제 종료 대신 실행될 로직을 추가하여 대처 가능하다.

 

문제 : 오류 발생 > 실행 정지

해결 : 오류 발생 > 오류 대처 > 정상 작동 

10.2 예외란? error

정수를 0으로 나누기

- ZeroDivisionError

# 정수를 0으로 나누기

print("4/0 = ", 4/0)

# ---------------------------------------------------------------------------
# ZeroDivisionError                         Traceback (most recent call last)
# <ipython-input-2-b0386c54c776> in <module>
#       1 # 0으로 나누기
#       2 
# ----> 3 print("4/0 = ", 4/0)

# ZeroDivisionError: division by zero

인덱스 범위를 벗어난 접근

- IndexError

# 인덱스를 범위를 벗어난 접근

lst = [1,2,3,4]
print(lst[999])

# IndexError                                Traceback (most recent call last)
# <ipython-input-3-94cd13c3b4a0> in <module>
#       2 
#       3 lst = [1,2,3,4]
# ----> 4 print(lst[999])

# IndexError: list index out of range

파일과 소켓에서 문제 발생

- FileNotFoundError

# 파일과 소켓 불일치, 누락

file = open("없는파일.txt", "r")

# ---------------------------------------------------------------------------
# FileNotFoundError                         Traceback (most recent call last)
# <ipython-input-8-c025b5b9fca3> in <module>
#       1 # 파일과 소켓 불일치, 누락
#       2 
# ----> 3 file = open("없는파일.txt", "r")
#       4 
#       5 # ---------------------------------------------------------------------------

# FileNotFoundError: [Errno 2] No such file or directory: '없는파일.txt'

실습: 예외 강제 발생

# 1 #
# 예외를 강제로 발생시켜보세요.

# 2 #
# 예외가 발생한 소스코드를 try: 블럭에 포함시키고, excpet: 블럭에 print()를 구현해 보세요.

# 예시
try:
  ㅈㄷㄱㅈㄷㄱ
except:
  print("예외 발생")

10.3 예외 처리 구현 방법

try: ~ except: ~ else: ~ finally:

더보기
try:
    x = int(input('나눌 숫자를 입력하세요: '))
    y = 10 / x
except:                      # 숫자를 0으로 나눠서 에러가 발생했을 때 실행됨
    print('숫자를 0으로 나눌 수 없습니다.')
else:                        # try의 코드에서 예외가 발생하지 않았을 때 실행됨
    print(y)
finally:                     # 예외 발생 여부와 상관없이 항상 실행됨
    print('코드 실행이 끝났습니다.')

if 조건문으로 예외 처리

# if 조건문 예외 처리의 한계

while True:
  
  div = int(input('10을 나눌 정수를 입력하세요: '))
  
  if div == 999:
    print('프로그램을 종료합니다.')
    break
  elif div != 0:
    res = 10 / div # 예외 예상 지점
    print(int(res))
  else:
    print('예외가 발생했습니다.')

try: ~ except 

try: 블럭의 오류 종류 상관없이, 모든 예외에 대해 except: 구문 실행

# 예상 오류
# 0 입력시, ZeroDivisionError
# 문자 입력시, ValueError

while True:

  try:
      div = int(input('10을 나눌 정수를 입력하세요: '))
      res = 10 / x # 예외 예상 지점
      print(res)
  except: # 예외 발생시 실행됨
      print('예외가 발생했습니다.')

try: ~ except 오류유형:

try: 블럭의 오류가, 특정 오류 유형일때 except: 구문 실행

# 0 입력시, ZeroDivisionError 은 예외 처리 대상이지만
# 문자 입력시, ValueError 에 대해서는 처리하지 못한다.

while True:

  try:
      div = int(input('10을 나눌 정수를 입력하세요: '))
      res = 10 / x # 예외 예상 지점
      print(res)
      
  except ZeroDivisionError: 
      print('예외가 발생했습니다.\n0으로 나눌 수 없습니다.')

try: ~ except 오류유형: ~ except 오류유형:

# 오류의 종류에 따라 각각 다른 실행 코드를 except 블럭에 작성할 수 있다.

while True:

  try:
      div = int(input('10을 나눌 정수를 입력하세요: '))
      res = 10 / x # 예외 예상 지점
      print(res)
      
  except ZeroDivisionError: 
      print('예외가 발생했습니다.\n0으로 나눌 수 없습니다.')
      
  except ValueError: 
      print('예외가 발생했습니다.\n입력값이 숫자가 아닙니다.')

10.4 예외 처리 예시

오류 무시

# 오류 발생되어도 강제적으로 다음 로직이 실행되도록 한다.

try:
  file = open("info.txt", "r")
except FileNotFoundError as e:
  pass
  print(e)

 

오류 발생에 상관없이 실행하는 finally:

# case1. 정수 입력시 정상 작동
# case2. 0 입력시, ZeroDivisionError
# case3. 문자 입력시, ValueError

while True:

  try:
    div = int(input('10을 나눌 정수를 입력하세요: '))
    res = 10 / div # 예외 예상 지점
    print(f"10/{div} = ", res)

  except: # 예외 발생시 실행됨
    print('예외가 발생했습니다.')
  
  finally:
    print('finally는 무조건 실행됩니다.\n')
# 문제
# finally 구문의 유무 비교

while True:

  try:
    div = int(input('10을 나눌 정수를 입력하세요: '))
    res = 10 / div # 예외 예상 지점
    print(f"10/{div} = ", res)

  except: # 예외 발생시 실행됨
    print('예외가 발생했습니다.')
  
  print('finally는 무조건 실행됩니다.\n')

함수 내부 사용

def write_text_file(filename, text):
  try:
    file = open(filename, "w")
    return
    file.write(text)
  except Exception as e:
    print(e)
  finally:
    file.close()

write_text_file("test.txt", "안녕하세요.")

반복문 내부 실행

while True:
  try:
    print("try 구문 실행")
    break
    print("break 뒤 구문")
  except:
    print("except 실행")
  finally:
    print("finally 실행")
  print("while 마지막 줄")
print("종료")

10.5 강제 예외 발생 처리

raise 사용 방법

try:
    x = int(input('3의 배수를 입력하세요: '))
    if x % 3 != 0:
        raise Exception('3의 배수가 아닙니다.') # 예외를 발생
    print(x)
    
except Exception as e:
    print('예외가 발생했습니다.', e)

함수에서 raise 적용 방법

def three_multiple():

    try:
        x = int(input('3의 배수 입하세요: '))
        if x % 3 != 0:
            raise Exception(f'입력하신 {x}는 3의 배수가 아닙니다.') # 예외 발생
        print(x)
        
    except Exception as e:  
        print('three_multiple 함수에 예외가 발생했습니다.', e)
        raise    # raise 예외 재실행 후 상위 코드 블록으로 전달
 
try:
    three_multiple()
    
except Exception as e:  # 하위 코드 블록에서도 예외 처리 실행
    print('스크립트 파일에 예외가 발생했습니다.', e)

10.6 예외 클래스 정의

class NotThreeMultipleError(Exception):    # Exception 상속
    def __init__(self):
        super().__init__('[예외] 3의 배수가 엽력되지 않았습니다.') # 오버라이딩
 
def three_multiple():
    try:
        x = int(input('3의 배수를 입력하세요: '))
        if x % 3 != 0:
            raise NotThreeMultipleError    # 예외 발생
        print("3의 배수:", x)
    except Exception as e:
        print('e 실행:', e)
 
three_multiple()

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.