Python

예외 처리

haventmetyou 2023. 10. 23. 16:43
try except로 사용
# try:
#     실행할 코드
# except:
#     예외가 발생했을 때 처리하는 코드

try:
    x = int(input('나눌 숫자 입력: '))
    y = 10 / x
    print(y)
except:    # 예외가 발생했을 때 실행됨
    print('오류 발생')
    
# 실행 결과
나눌 숫자 입력: 0
오류 발생

예외 발생 시 해당 줄에서 바로 코드 실행 중단, 바로 except로 넘어가 코드 실행

try의 y = 10 / x, print(y) 모두 실행되지 x

try 코드에서 에러가 발생했을 때만 except 코드가 실행됨

 

특정 예외만 처리

# try:
#     실행할 코드
# except 예외이름:
#     예외가 발생했을 때 처리하는 코드

y = [10, 20, 30]

try:
    index, x = map(int, input('인덱스와 나눌 숫자 입력: ').split())
    print(y[index] / x)
except ZeroDivisionError:    # 숫자를 0으로 나눠서 에러가 발생했을 때 실행
    print('숫자를 0으로 나눌 수 없음')
except IndexError:           # 범위를 벗어난 인덱스에 접근하여 에러가 발생했을 때 실행
    print('잘못된 인덱스')
    
# 실행 결과

인덱스와 나눌 숫자 입력: 2 0
숫자를 0으로 나눌 수 없음

인덱스와 나눌 숫자 입력: 3 5
잘못된 인덱스    # 위 인덱스는 0, 1, 2까지 존재

 

예외의 에러 메시지 받아 오기

# try:
#     실행할 코드
# except 예외 as 변수:
#     예외가 발생했을 때 처리하는 코드

y = [10, 20, 30]

try:
    index, x = map(int, input('인덱스와 나눌 숫자 입력: ').split())
    print(y[index] / x)
except ZeroDivisionError as e:               # as 뒤에 변수를 지정하면 에러를 받아 옴
    print('숫자를 0으로 나눌 수 없음', e)    # e에 저장된 에러 메시지 출력
except IndexError as e:           
    print('잘못된 인덱스입니다', e)
    
# 실행 결과

인덱스와 나눌 숫자 입력: 2 0
숫자를 0으로 나눌 수 없음 division by zero

인덱스와 나눌 숫자 입력: 3 5
잘못된 인덱스입니다 list index out of range

모든 예외의 에러 메시지 출력할 때 Exception 사용

except Exception as e:
    print('예외가 발생했습니다', e)

 

else와 finally 사용
# try:
#     실행할 코드
# except:
#     예외가 발생했을 때 처리하는 코드
# else:
#     예외가 발생하지 않았을 때 실행할 코드
# else는 except 바로 다음에 와야 하며 except 생략 불가능

try:
    x = int(input('나눌 숫자 입력: '))
    y = 10 / x
except ZeroDivisionError:
    print('숫자를 0으로 나눌 수 없음')
else:
    print(y)
    
# 실행 결과

나눌 숫자 입력: 2
5.0

나눌 숫자 입력: 0
숫자를 0으로 나눌 수 없음

 

예외와 상관없이 항상 코드 실행

# try:
#     실행할 코드
# except:
#     예외가 발생했을 때 처리하는 코드
# else:
#     예외가 발생하지 않았을 때 실행할 코드
# finally:
#     예외 발생 여부와 상관없이 항상 실행할 코드
# finally는 except와 else를 생략할 수 있음


try:
    x = int(input('나눌 숫자 입력: '))
    y = 10 / x
except ZeroDivisionError:
    print('숫자를 0으로 나눌 수 없음')
else:
    print(y)
finally:
    print('코드 실행이 끝났습니다')
    
# 실행 결과

나눌 숫자 입력: 2
5.0
코드 실행이 끝났습니다

나눌 숫자 입력: 0
숫자를 0으로 나눌 수 없음
코드 실행이 끝났습니다

 

예외 발생시키기
# raise 예외('에러메시지')

try:
    x = int(input('3의 배수 입력: '))
    if x % 3 != 0:                                # x가 3의 배수가 아니면
        raise Exception('3의 배수가 아닙니다')    # 예외를 발생시킴
    print(x)
except Exception as e:                            # 예외가 발생했을 때 실행됨
    print('예외 발생', e)
    
# 실행 결과

3의 배수 입력: 3
3

3의 배수 입력: 1
예외 발생 3의 배수가 아닙니다

 

raise의 처리 과정

def three_multiple():
    x = int(input('3의 배수 입력: '))
    if x % 3 != 0:
        raise Exception('3의 배수가 아님')    # x가 3의 배수가 아니면 예외 발생
    print(x)                                  # 현재 함수 안에 except가 없으므로
                                              # 예외를 상위 코드 블록으로 넘김

try:
    three_multiple()
except Exception as e:    # 하위 코드 블록에서 예외가 발생해도 실행됨
    print('예외 발생', e)
    
# 실행 결과

3의 배수 입력: 5
예외 발생 3의 배수가 아님

three_multiple 함수는 안에 try except가 없는 상태에서 raise로 예외 발생, 이렇게 되면 함수 바깥에 있는 except에서 예외 처리

예외가 발생하더랃 현재 코드 블록에서 처리해 줄 except가 없다면 except가 나올 때까지 계속 상위 코드 블록으로 올라감

함수 바깥에도 처리해 줄 except가 없다면 코드 실행 중지, 에러 표시

 

현재 예외 다시 발생시키기

try except에서 처리한 예외를 다시 발생시킴

except 안에서 raise를 사용하면 현재 예외 다시 발생시킴 (re-raise)

def three_multiple():
    try:
        x = int(input('3의 배수 입력: '))
        if x % 3 != 0:
            raise Exception('3의 배수가 아님')    # x가 3의 배수가 아니면 예외 발생
        print(x)
    except Exception as e:                        # 함수 안에서 예외 처리
        print('three_multiple 함수에서 예외 발생', e)
        raise    # raise로 현재 예외를 다시 발생시켜 상위 코드 블록으로 넘김

try:
    three_multiple()
except Exception as e:    # 하위 코드 블록에서 예외가 발생해도 실행됨
    print('스크립트 파일에서 예외 발생', e)
    
# 실행 결과

3의 배수 입력: 5
three_multiple 함수에서 예외 발생 3의 배수가 아님
스크립트 파일에서 예외 발생 3의 배수가 아님

 

예외 만들기
# class 예외이름(Exception):
#     def __init__(self):
#         super().__init__('에러메시지')

class NotThreeMultipleError(Exception):    # Exception을 상속받아 새로운 예외를 만듦
    def __init__(self):
        super().__init__('3의 배수가 아님')

def three_multiple():
    try:
        x = int(input('3의 배수 입력: '))
        if x % 3 != 0:                     # x가 3의 배수가 아니면
            raise NotThreeMultipleError    # NotThreeMultipleError 예외를 발생시킴
        print(x)
    except Exception as e:                       
        print('예외 발생', e)

three_multiple()

# 실행 결과

3의 배수 입력: 5
예외 발생 3의 배수가 아님