본문 바로가기
Programming/Python

17. 예외 고급

by IT learning 2021. 3. 22.
728x90

프로그램을 개발하다 보면 수많은 오류를 만나게 된다.

또한 프로그램을 만들면서 모든 오류를 예측하고 만드는 경우는 없다.

개발이 완료가 됐다고 해도, 예측하지 못한 예외들 때문에 유지보수를 해줘야 한다.

 

오늘은 그러한 예외를 조금은 다룰수 있는 기능들에 대해 소개하겠다.

 

예외 객체

처음 예외 객체를 사용해 보면 '예외의 종류'가 뭔지 몰라 당황하는 경우가 있다.

그럴땐 그냥 Exception을 사용하면 된다.

try:
    number_input_a = int(input("정수 입력 >"))
    print("원의 반지름 :", number_input_a)
    print("원의 둘레 :",2 * 3.14 * number_input_a)
    print("원의 넓이 :", 3.14 * number_input_a * number_input_a)
except Exception as exception :
    print("type(exception):", type(exception))
    print("exception:", exception)

위 코드를 보자.

정수를 입력하고, 그에 해당하는 정보들을 반환하는 코드이다.

이 중 정수가 아닐경우 예외가 발생해 except 구문으로 들어오게 된다.

예외의 종류를 모르면 Exception을 설정해 놓고 사용하면된다.

위 코드의 실행결과이다.

처음 실행시켰을땐 정수를 입력하여 결과를 도출해냈다.

두번째에는 문자를 입력시켜 예외를 도출하게 했다. except 구문으로 들어가 exception의 타입을 출력하고, 예외의 이유를 설명해준다.

이러한 예외를 나중에 큰 프로그램에서 발견했다면, 수정을 요청하는 메일이나 메신저에 복사하여 붙여주면 유지보수에 도움이 된다고 한다.

 

예외 구분하기

예외 객체를 사용하면 except 구문을 if 조건문처럼 사용해서 예외를 구분할 수 있다.

# 여러 가지 예외가 발생할 수 있는 코드
list_number = [52,273,32,72,100]

try:
    number_input = int(input("정수 입력 > "))
    print("{}번째 요소: {}".format(number_input, list_number[number_input]))
except Exception as exception:
    print("type(exception):", type(exception))
    print("exception:", exception)

위 코드를 보자.

위 코드는 여러 가지 예외가 발생할 수 있는 코드이다.

그러니까 정수 이외에 예외들이 많다.

위 코드의 실행결과이다.

실행결과를 보면 알 수 있듯이, 정수 이외에 해당하는 인덱스의 값이 아니거나, 문자를 입력하여 도출해내는 방법이 존재하기 마련이다.

예외들을 보면 인덱스의 예외는 IndexError, 정수가 아닌 것의 예외는 ValueError 로 구분된다.

이 예외들을 구분하여 처리가 가능하다.

 

예외 구분하기

list_number = [52,273,32,72,100]

try:
    number_input = int(input("정수 입력 > "))
    print("{}번째 요소: {}".format(number_input, list_number[number_input]))
except ValueError:
    print("정수를 입력해 주세요!")
except IndexError:
    print("리스트의 인덱스를 벗어났어요!")

아까 봤던 ValueError IndexError 를 이용하여 예외를 구분시켜 나오게 했다.

위 코드의 실행결과이다.

실행결과를 보면 알 수 있듯이 각 예외에서 해당하는 문구들이 나오게 됐다.

 

예외 구분 구문과 예외 객체

예외를 구분할 때 각각의 except 구문 뒤에 예외 객체를 붙여 활용할 수도 있다. as 키워드를 사용하면 된다.

list_number = [52,273,32,72,100]

try:
    number_input = int(input("정수 입력 > "))
    print("{}번째 요소: {}".format(number_input, list_number[number_input]))
except ValueError as exception:
    print("정수를 입력해 주세요!")
    print("exception:", exception)
except IndexError as exception:
    print("리스트의 인덱스를 벗어났어요!")
    print("exception:", exception)

위 코드의 실행결과이다.

실행은 아래에 exception 구문이 추가 된 것 말고는 위 코드와 다른게 없다.

아까 Exception을 썻던 것처럼 예외 객체를 붙여서 사용할 수 있는 것이다.

 

모든 예외 잡기

만약에 예외 조건이 일치하는 것이 없다면 당연히 예외가 발생하면 프로그램이 종료될 것이다.

list_number = [52,273,32,72,100]

try:
    number_input = int(input("정수 입력 > "))
    print("{}번째 요소: {}".format(number_input, list_number[number_input]))
    예외.발생해주세요()
except ValueError as exception:
    print("정수를 입력해 주세요!")
    print("exception:", exception)
except IndexError as exception:
    print("리스트의 인덱스를 벗어났어요!")
    print("exception:", exception)

위 코드를 보면 try 구문 중간에 예외.발생해주세요() 라는 함수가 존재한다. 

이 함수 때문에 이 코드는 예외가 발생한다. 이 코드의 예외는 NameError 일텐데, 예외 처리 구문에 NameError가 없다.

그러면 프로그램은 강제 종료된다. 그렇다면 무슨 에러가 나든간에 강제종료가 안되는 건 없을까?

list_number = [52,273,32,72,100]

try:
    number_input = int(input("정수 입력 > "))
    print("{}번째 요소: {}".format(number_input, list_number[number_input]))
    예외.발생해주세요()
except ValueError as exception:
    print("정수를 입력해 주세요!")
    print("exception:", exception)
except IndexError as exception:
    print("리스트의 인덱스를 벗어났어요!")
    print("exception:", exception)
except Exception as exception:
    print("미리 파악하지 못한 예외가 발생했습니다.")
    print(type(exception), exception)

위 코드가 그 답이다.

else 구문 처럼 마지막에는 모든 예외의 부모라고 할 수 있는 Exception을 넣어서 프로그램이 죽지 않게 하는 것이다.

이러면 강제종료 되지 않고 '미리 파악하지 못한 예외가 발생했습니다' 라는 문구와 함께 예외 종류가 뜨게 된다.

 

rasie 구문

프로그램이 강제 종료되는 것을 막기 위해 예외는 꼭 처리해야 한다.

하지만 개발하는 동안에는 '아직 구현된 부분이 아니니 이 곳은 문제가 생기게 두자' 나 '여긴 큰일 날 부분이니 문제 생기게 만들자'

라는 이유로 강제 종료 시키는 것 들도 존재하기 마련이다. 

아직 구현되지 않은 부분이므로 일부러 예외를 발생시켜 프로그램을 죽게 만들어 잊어버리지 않도록 하는 것이다.

이때 rasie 키워드를 사용한다.

number = int(input("정수 입력 > "))

if number > 0:
    raise NotImplementedError
else:
    raise NotImplementedError
    
# 예외를 강제로 발생시키는 기능을 한다.

 사용법은 간단하다. rasie 뒤에 자신이 오류를 시킬 예외 구문을 추가 하면된다.

위 코드의 실행결과이다.

실행결과를 보면 알 수 있듯이, 아직 구현하지 않은 부분에 rasie 키워드를 사용해 예외를 도출하게끔 나오게 했다.

 

정리
예외 객체
는 예외와 관련된 정보를 답고 있는 객체이다.
raise 구문은 예외를 강제로 발생시킬 때 사용하는 구문이다.
728x90

'Programming > Python' 카테고리의 다른 글

19. 외부 모듈(Beautiful Soup, Flask 모듈)  (0) 2021.03.24
18. 표준 모듈  (0) 2021.03.23
16. 구문 오류와 예외  (0) 2021.03.21
15. 함수 고급(파일 처리, 제네레이터)  (0) 2021.03.20
14. 함수 고급(람다, 튜플)  (0) 2021.03.20

댓글

IT_learning's Commit