본문 바로가기
SK 행복성장캠퍼스/Python 기초

0907_6일차_예외 처리

by NickNuma 2020. 9. 8.

예외 처리에 대한 설명입니다.

 


일단 예외라는 것은 일반적으로 오류 또는 에러라는 개념을 뜻합니다.
예외가 발생되면 '비정상 종료'가 되는데 비정상 종료 상황을 없애주기 위해서 예외처리를 사용합니다.

"""
   예외처리
      1) 예외 (exception)
         일반적으로 오류 또는 에러라는 개념

      2) 예외 발생
         프로그램이 실행중에 예외가 발생되면 '비정상종료'된다.

      3) 예외 처리 (exception handling)
         예외가 발생된 문장 이후의 문장은 정상적으로 수행되도록 처리하는 방법. ==> 정상 종료되록 처리하는 방법
"""         

 

예외처리를 담당하는 클래스는 이렇습니다.

"""
         문법 :
            가) 예외처리 담당하는 클래스 제공
                - SyntaxError       : 문법 오류
                - NameError         : 참조변수가 없을 때 발생
                - ZeroDivisionError : 0으로 나눴을 때 발생
                - IndexError        : 인덱스 범위 오버(over)
                - KeyError          : dict에서 없는 key값 접근시 발생
                - ValueError        : 참조값이 없을 때
                - FileNotFoundError : 없는 파일 접근시
                - TypeError         : 타입이 일치하지 않는 경우
                    ===> 사용자 정의 예외 클래스 생성 가능
"""

 

예외처리 문법입니다.
try:
   에러 확인할 문장 1
   에러 확인할 문장 2
except 예외클래스명 as 별칭:
    예외가 발생되었을 때 실행 문장 ==> 예외 발생 이유 출력

"""
            나) try:
                    실행하고자 하는 문장 1
                    실행하고자 하는 문장 2
                except 예외클래스명 as 별칭:
                    예외가 발생되었을 때 처리 (실행) 문장  ==> 예외가 발생된 이유를 알려주는 작업

                * 예외 클래스는 적합한 클래스를 사용해야 한다.
                  임의로 아무 예외처리 담당 클래스를 지정하면 예외처리가 되지 않는다.
                  => 단, 부모 클래스인 Exception을 쓰면 모든 예외 처리 가능
"""

 

모든 클래스는 상속관계로 이루어져있으며, 예외 클래스의 부모는 Exception, 모든 클래스의 부모는 Object 클래스입니다.

"""     
     4) 모든 클래스는 상속관계로 되어있다.
        예외 클래스의 부모 클래스명은 Exception 이다.   ( 모든 클래스의 부모, 최상위 클래스 : Object )
"""        

 

 


기본 예제입니다.

print("start")                               # start
try:
    num = 0
    result = 10 / num
    print("결과값:", result)
except ZeroDivisionError as e:
    print("0으로 나누어 예외가 발생하였습니다.")   # 0으로 나누어 예외가 발생하였습니다.
print("end(정상종료)")                          # end(정상종료)

 

적합한 예외처리 클래스를 사용하지 않으면 예외처리가 되지 않고 Error가 발생합니다.

# 에러난다.
print("start")
try:
    num = 0
    result = 10 / num
    print("결과값:", result)
except NameError as e:          # 적합한 예외처리가 아니기때문에 Error
    print("0으로 나누어 예외가 발생하였습니다.")
print("end(정상종료)")

 

예외 클래스의 부모인 Exception 클래스를 사용하면 모든 예외처리가 가능합니다.

# 예외 클래스의 부모 클래스를 사용하면 모든 예외처리가 가능하다.
print("start")              # start
try:
    num = 0
    result = 10 / num
    print("결과값:", result)
except Exception as e:              # 예외 클래스의 부모 클래스 : Exception
    print("0으로 나누어 예외가 발생하였습니다.")   # 0으로 나누어 예외가 발생하였습니다.
print("end(정상종료)")               # end(정상종료)

 


mro()함수를 이용하여 현 클래스의 계층 구조를 확인할 수 있습니다.

# 클래스 계층 구조 확인
print("ZeroDivisionError 계층구조:", ZeroDivisionError.mro())
# ZeroDivisionError 계층구조: [<class 'ZeroDivisionError'>, <class 'ArithmeticError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>]

 


다중 예외처리입니다. try문에서 error가 날 것 같은데 확실히 하나의 예외 클래스가 아니라 조금 여러가지가 의심될 때 사용할 수 있을 것 같습니다.
try:
   에러 확인할 문장 1
   에러 확인할 문장 2
except 예외클래스명 as 별칭:
    예외가 발생되었을 때 실행 문장 ==> 예외 발생 이유 출력
except 예외클래스명 as 별칭:
    예외가 발생되었을 때 실행 문장 ==> 예외 발생 이유 출력

"""
     5) 다중 except문      # 근데 오류가 있으면 try문이 다 도는게 아닌데 왜 다중을 쓸까?
                try:
                    실행하고자 하는 문장 1   ( NameError 발생 가능 )
                    실행하고자 하는 문장 2   ( IndexError 발생 가능 )
                    실행하고자 하는 문장 3   ( 알 수 없는 Error 발생 가능 )
                except NameError as 별칭:
                    pass
                except IndexError as 별칭:
                    pass
                except Exception as 별칭:         # Exception 만으로도 다 잡을 수 있지만
                    pass                         # 디테일하게 잡아서 예외 발생 이유를 알려주는 것을 *권장* (어쩔수 없을 때 사용.)
"""

 


다중 예외처리 예제입니다.
에러가 나올때까지 try문을 탐색합니다. 하지만 탐색 중에 에러문이 발생하면 이후 try문은 continue (skip)됩니다.

print("start")          # start

try:
    x = [10, 20]    # Index Error
    print(x[4])

    n = [10, 20]     # TypeError ==> list + tuple
    m = (3, 4)
    result = n + m
    print("결과값:", result)

except IndexError as e:             # print(x[4])
    print("IndexError 발생 :", e)    # IndexError 발생 : list index out of range

except TypeError as e:              # result = n + m
    print("TypeError 발생", e)


print("End(정상종료)")                # End(정상종료)

 


Finally문입니다. ===> 반드시 수행되는 문장입니다.

"""    
    6. Finally 문
        try:
            실행하고자 하는 문장 1
            실행하고자 하는 문장 2
        except 예외클래스명 as 별칭:
            pass
        finally:
            반드시 수행되는 문장 (예외가 발생여부와 상관없이 무조건 실행)

"""
print("start")      # start

try:
    x = [10, 20]    # Index Error
    print(x[4])

except IndexError as e:             # print(x[4])
    print("IndexError 발생 :", e)    # IndexError 발생 : list index out of range 
finally:
    print("반드시 수행")              # 반드시 수행


print("End(정상종료)")      # End(정상종료)

 


사용자가 강제적으로 예외를 발생시킬 수 있습니다.
raise 예외클래스("메세지") 를 사용합니다.

예제 1입니다. raise 예외클래스("메세지")를 사용하여 사용자 정의 예외를 발생시킵니다.

# raise 예외클래스("메세지")   ===> 비정상종료
import random
print('start')          # start
result = random.randrange(0, 3)
print(result)           # 0
if result == 0:
    raise Exception("0이 나와 예외 발생")      #raise Exception("0이 나와 예외 발생")
print('정상종료')


예제 2입니다. raise 사용자 정의 예외 발생 후, 해당 예외를 예외처리합니다.

# 사용자정의 예외처리를 예외처리
import random
print('start')          # start
try:
    result = random.randrange(0, 3)
    print(result)
    if result == 0:     # 0
     raise Exception("0이 나와 예외 발생")     # 0이 나와 예외 발생
except Exception as e:
    print(e)
print('정상종료')       # 정상종료

 

주중에는 간단하게 설명을 하고 주말에 복습겸 다듬도록 하겠습니다.

그럼 이만~

반응형

댓글