이해하기 쉬운 파이썬 3.6 - 7회차

2018. 7. 16. 17:36언어별 정리 자료/Python

이해하기 쉬운 파이썬 3.6 - 7회차


    지난 시간에는 여러가지 남이 작성한, 혹은 미리 만들어 두었던 모듈을 사용하는 방법에 대해서 공부했습니다. 이번에는 그러한 모듈에서 발생하는 여러가지 특수 Case들을 분석하는 방법을 진행 해 보도록 하겠습니다.

예외란?
    파이썬에서 기본적으로 지정된 혹은 사용자가 지정한 특정한 에러 상황에서 나타나는 것을 "예외( Exception )" 이라고 합니다. 이러한 예외가 호출되면 파이썬 프로그램은 작동을 멈춘 뒤, 관련 예외 상황에 대한 설명을 띄우게 됩니다. 다음과 같은 종류가 있습니다. 물론 하단에 존재하는 Error 외에도 Error의 종류는 다양합니다.


 TypeError 

 잘못된 type으로 함수가 인자를 호출 할 경우.

 NameError 

 알 수 없는 변수( 변수 이름에 오타나 delete 된 변수 )가 사용 된 경우.

 ValueError 

 옳은 type으로 함수가 인자를 호출하였지만, 값이 적절하지 못한 경우.

 SyntaxError 

 문법적인 오류 ( 오타 등 )

 ImportError 

 사용하고자 하는 모듈 명이 잘못되거나, 모듈이 설치가 되지 않았을 경우.

 IndexError 

 배열이나 리스트의 index가 범위 밖이거나, 잘못 된 경우.

 ZeroDivisionError 

 0으로 나누기를 실행한 경우.


    파이썬에서 이런 에러가 발생 한 경우, 에러의 이름과 설명, 에러가 발생한 함수 stack( 어느 함수의 어느 부분을 의미 )이 나옵니다. 이런 에러의 이름과 설명을 통해 개발자들은 모르는 에러를 찾아보면서 개발 하여야 합니다.


예외 처리
- except & else

    사용자는 항상 발생 가능한 오류에 대해서 예외처리를 해 주어야 합니다. 다음은 기본적인 예외 처리 방법입니다. 특정한 에러 상황일 때 except 예약어를 통해서 각 에러 상황 별로, 혹은 여러 에러 상황을 한번에 묶어서 처리 가능합니다. 오류가 생길 수 있는 부분은 try로 묶어서 처리 해야 합니다. 또한 위에서 부터 except 구문을 수행하며, 한번 except 밑의 구문을 수행하면 다른 except 구문은 실행하지 않습니다. 다음 코드로 직접 살펴보도록 하겠습니다.

try:
    # 에러가 생길 수 있는 부분.
    import numpy                         # ImportError 가능.
    x = int(input("X : "))
    y = int(input("Y : "))
    print(" X / Y = " + str(x / y))    # ZeroDivisionError 가능.
except ZeroDivisionError:
    print("Y 가 0입니다.")
except ImportError:
    print("Y는 0이 아니나, numpy 모듈이 존재하지 않습니다.")

    ZeroDivisionError 를 except 하였으면, ImportError를 except 한 부분은 실행하지 않습니다. 또한 에러가 생기지 않았다면 else 로 묶어서 처리 가능합니다.

try:
    # 에러가 생길 수 있는 부분.
    import numpy                         # ImportError 가능.
    x = int(input("X : "))
    y = int(input("Y : "))
    print(" X / Y = " + str(x / y))    # ZeroDivisionError 가능.
except ZeroDivisionError:
    print("Y 가 0입니다.")
except ImportError:
    print("Y는 0이 아니나, numpy 모듈이 존재하지 않습니다.")
else :
    print("에러 없이 잘 실행되었습니다.")

    역시 except 가 실행되면 else는 수행되지 않습니다. 에러는 1개씩 나눠쓰지 않고, 같이 한번에 처리 할 수 도 있습니다. 또한 except 만 써서 except 되지 않은 에러를 모두 한꺼번에 처리 가능합니다.

try:
    # 에러가 생길 수 있는 부분.
    import numpy                         # ImportError 가능.
    x = int(input("X : "))
    y = int(input("Y : "))
    print(" X / Y = " + str(x / y))    # ZeroDivisionError 가능.
except (ZeroDivisionError, ImportError):    # 에러 2가지 처리.
    print("0으로 나누거나, numpy 모듈이 없는 에러가 발생하였습니다.")
except :                                                  # 한꺼번에 모든 에러 처리. ( Zero, Import 제외 )
    pass                                                   # 아무런 동작도 하지 않음.
else :
    print("에러 없이 잘 실행되었습니다.")

    pass 명령어는 아무런 동작도 하지 않고 그 줄을 넘어가도록 하는 예약어입니다.

- finally

    예외 처리 이외에도 자주 쓰이는 예약어입니다. 주로 "~~ 한 다음 마지막으로 ~~를 하여라" 라는 식의  용어에서 사용 가능합니다. else는 except가 발생하지 않았을 경우 실행하는 구문이라면 finally는 except가 발생 했어도 수행하는 구문입니다.

try:
    # 에러가 생길 수 있는 부분.
    import numpy                         # ImportError 가능.
    x = int(input("X : "))
    y = int(input("Y : "))
    print(" X / Y = " + str(x / y))    # ZeroDivisionError 가능.
except (ZeroDivisionError, ImportError):    # 에러 2가지 처리.
    print("0으로 나누거나, numpy 모듈이 없는 에러가 발생하였습니다.")
except :                                                  # 한꺼번에 모든 에러 처리. ( Zero, Import 제외 )
    pass                                                   # 아무런 동작도 하지 않음.
else :
    print("에러 없이 잘 실행되었습니다.")
finally :        
    y = int(input("Y : "))
    print(" X / Y = " + str(x / y))


예외 불러 일으키기
- raise

    이외에도 자신이 만든 함수에서 예외를 호출해야 할 때가 있습니다. 정수 a와 b를 입력받아 a * b 를 return 하지만, b 가 홀수 일때만 계산하는 oddMulti(a, b) 함수를 만든다고 합시다. 이는 C 언어 형식으로 다음과 같이 표현 가능합니다. ( C 언어는 Exception ( 예외 처리 ) 가 없는 대표적인 언어 입니다. )

def oddMulti(a, b):
    if b % 2 == 1:
        return -1
    else :
        return a * b

다만 진짜로 계산 결과가 -1 인 경우에는 이런 함수는 문제가 생길 수 있습니다. 따라서 다음과 같이 에러를 발생시키는 코드를 작성해야 합니다. 정수인지 판별 한 뒤, b 가 홀수인지 판별하게 하였고, Error 이름은 임의로 원래 존재하지 않는 이름으로 지어주었습니다.

def oddMulti(a, b):
    if type(a) != type(1) and type(b) != type(1):
        raise NotIntError
    if b % 2 == 1:
        raise NotOddError
    else :
        return a * b


위와같이 에러를 발생 시켜 진행 할 수 있습니다.