TIL

TIL.38 예외 발생시키기 및 만들기

codermun 2020. 11. 15. 16:37
728x90
반응형

## 예외 발생시키기 및 만들기

# 이전까지는 파이썬에서 정해진 예외만 처리하으면 이번에는 직접 예외를 발생시켜 보자.

## 예외를 발생시킬 때는 raise에 예외를 지정하고 에러 메시지를 넣는다(에러 메시지는 생략 할 수 있음)

# raise 예외('에러메시지')

try:
    x = int(input('3의 배수를 입력하세요: '))
    if x % 3 != 0:                                 # x가 3의 배수가 아니면
        raise Exception('3의 배수가 아닙니다.')    # 예외를 발생시킴
    print(x)
except Exception as e:                             # 예외가 발생했을 때 실행됨
    print('예외가 발생했습니다.', e)      # raise 의 에러메시지가 e에 들어간다.
    
# 3의 배수를 입력하세요: 5
# 예외가 발생했습니다. 3의 배수가 아닙니다.

 

## raise의 처리 과정

# 다음은 함수 안에서 raise를 사용하지만 함수 안에는 try except가 없는 상태이다.

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

try:
    three_multiple()
except Exception as e:    # 하위 코드 블록에서 예외가 발생해도 실행됨(함수바깥에 except가 있는 상태)
    print('예외가 발생했습니다.', e)

# 3의 배수를 입력하세요: 100
# 예외가 발생했습니다. 3의 배수가 아닙니다.

 

## three_multiple 함수는 안에 try except가 없는 상태에서 raise로 예외를 발생

## 이렇게 되면 함수 바깥에 있는 except에서 예외가 처리된다.

## 즉, 예외가 발생하더라도 

   현재 코드 블럭에서 처리해줄 except가 없다면 except가 나올때까지 예외를 계속 상위 코드 블럭으로 넘기게 된다.

## 만약 함수 바깥에도 처리해줄 except가 없다면 코드 실행은 중지되고 에러가 표시된다.

three_multiple()
3의 배수를 입력하세요: 5 (입력)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    three_multiple()
  File "C:\project\try_except_function_raise.py", line 4, in three_multiple
    raise Exception('3의 배수가 아닙니다.')    # 예외를 발생시킴
Exception: 3의 배수가 아닙니다.

# 직접 three_multiple 함수를 호출했으므로 except가 없는 상태이다.

## 현재 예외를 다시 발생시키기

## try except에서 처리한 예외를 다시 발생시키는 방법으로

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

# raise

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

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

## three_multiple 함수 안에서 발생한 예외를 함수 안의 except에서 한 번 처리하고, 

## raise로 예외를 다시 발생시켜서 상위 코드 블록으로 넘겼다. 

## 그 다음에 함수 바깥의 except에서 예외를 처리했다. 이런 방식으로 같은 예외를 계속 처리해줄 수 있다.


## 참고

## raise만 사용하면 같은 예외를 상위 코드 블록으로 넘기지만 

    raise에 다른 예외를 지정하고 에러 메시지를 넣을 수도 있다.

# raise 예외('에러메시지')

 

        if x % 3 != 0:
            raise Exception('3의 배수가 아닙니다.')
        print(x)
    except Exception as e:
        print('three_multiple 함수에서 예외가 발생했습니다.', e)
        raise RuntimeError('three_multiple 함수에서 예외가 발생했습니다.') ## 참고

 

## assert로 예외 발생시키기


## 이번에는 프로그래머(사용자)가 직접 예외를 만들어보자(발생시키는것과 다르다.)

#프로그래머가 직접 만든 예외를 "사용자 정의 예외"라고 한다.

## 예외를 만드는 방법은 Exception을 상속받아서 새로운 클래스를 만들면 된다.

## 그리고 __init__ 메서드에서 기반 클래스의 __init__ 메서드를 호출하면서 에러 메시지를 넣어주면 된다.

# class 예외이름(Exception):

#     def __init__(self):

#         super().__init__('에러메시지')

class NotThreeMultipleError(Exception):    # Exception을 상속받아서 새로운 예외를 만듦
    def __init__(self):
        super().__init__('3의 배수가 아닙니다.') 
        #suoer를 이용해 기반클래스의 __init__메서드를 호출하면서 에러메시지를 넣어줌
 

def three_multiple():
    try:
        x = int(input('3의 배수를 입력하세요: '))
        if x % 3 != 0:                     # x가 3의 배수가 아니면
            raise NotThreeMultipleError    # NotThreeMultipleError 예외를 발생시킴
        print(x)                           # 3의 배수면 바로 프린트
    except Exception as e:
        print('예외가 발생했습니다.', e)
 
three_multiple()

# 3의 배수를 입력하세요: 5

# 예외가 발생했습니다. 3의 배수가 아닙니다.

 

## 아래와 같이 Exception만 상속받고 pass를 넣어서 아무것도 구현하지 않아도 된다.

## 대신 이때는 예외를 발생시킬때 에러메시지를 넣어줘야 한다.

class NotThreeMultipleError(Exception):    # Exception만 상속받고
    pass                                   # 아무것도 구현하지 않음
def three_multiple():
    try:
        x = int(input('3의 배수를 입력하세요: '))
        if x % 3 != 0:                     # x가 3의 배수가 아니면
            raise NotThreeMultipleError('3의 배수가 아닙니다.')    # 예외를 발생시킬 때 에러 메시지를 넣음
        print(x)                           # 3의 배수면 바로 프린트
    except Exception as e:
        print('예외가 발생했습니다.', e)

 three_multiple()

# 3의 배수를 입력하세요: 5

# 예외가 발생했습니다. 3의 배수가 아닙니다.

728x90
반응형