본문 바로가기
Python

[Python] 예외처리 - try, except, else, finally

by Gom Guard 2017. 12. 28.


예외처리 - 기본 흐름 



  • 프로그래밍을 하다보면 필연적으로 수많은 오류들에 직면하게 됩니다. 오류가 발생하는 것이 보다 완성도 높은 프로그램을 만드는데 필요하긴 합니다만 상황에 따라 오류를 무시해야 할 경우도 있고, 오류에 따라 적절한 조치를 취하고 싶을 경우들이 있습니다. 이런 경우들을 해결하기 위해 파이썬은 예외 처리 기능을 지원합니다.

  • 파이썬의 예외 처리는 4가지로 이루어져 있습니다. try, except, else, finally 로 총 4가지 입니다만, 예외 처리시 이 4가지를 모두 사용할 필요는 없습니다.



예외처리 - try | except 

  • 가장 기본적으로 사용되는 절은 try 절과 except 절 입니다. try 안에는 기본적으로 실행하는 코드를 넣고 except 절에는 에러가 발생했을 경우 시행할 코드를 작성합니다.

  • 첫 번째 사용방법은 try, except 만 사용하는 방법입니다.

try:
print(5/0)
except:
print('wrong division')

    • 결과는 wrong division 이라는 문자열이 출력됩니다. try, except 만 사용한다면 어떠한 종류의 에러가 발생하더라도 except 절의 코드가 실행됩니다.

  • 두 번째 사용방법은 발생 오류를 except 절에 작성하는 방법입니다.

try:
    print(5/0)
except ZeroDivisionError:
    print('wrong division')


    • ZeroDivisionError 이라는 오류를 명시해주었습니다. 이 경우 다른 에러가 발생하면 except 절에서 처리하지 않습니다.

  • 세 번째 방법은 발생 오류와 오류메시지 변수까지 except 절에 작성하는 방법입니다.

try:
    print(5/0)
except ZeroDivisionError as e:
    print(e)

    • 이 코드는 'division by zero' 라는 메시지를 출력합니다. ZeroDivisionError 에러에 저장되어있는 string 을 출력하게 됩니다.



예외처리 - try | except | else 

  • 예외처리의 기본인 try 절과 except 절에 else 절을 추가해서 에외처리문을 구성할 수 있습니다. else 절은 예외가 발생하지 않아 except 절을 실행하지 않았을 경우 실행되는 절 입니다.

try:
print(5/1)
except:
print('error')
else:
print('no error')

  • 이 코드는 5.0 과 'no error' 를 출력합니다. try 절에서 문제가 없었기 때문에 except 절이 실행되지 않고 else 절이 실행되는 것을 볼 수 있습니다.



예외처리 - try | except | finally 

  • finally 절은 try 절에서 예외의 발생여부에 관계없이 항상 실행되는 절 입니다.

try:
print(5/0)
except:
print('error')
finally:
print('end')



  • 이 코드는 'error' 과 'end' 문자열을 출력합니다. 에러가 나더라도 finally 절은 실행되는 것을 알 수 있습니다.


예외처리 - 여러개의 에러 처리하기 

  • 코드에서 예외는 보통 한 가지만 나타나지 않습니다. 어떤 예외가 나와도 동일하게 처리할 수도 있지만, 다른 예외가 발생하면 다르게 처리하는 것이 좋은 예외처리 방법입니다.

  try:
    print(5/0)
    print(c)
    
except NameError as e:
    print(e)
except ZeroDivisionError as e:
    print(e)

  • 위의 코드는 변수가 설정되지 않았을 경우 발생하는 에러인 NameError 과 분모가 0 일 경우 발생하는 ZeroDivisionError 에러를 예외처리 해준 코드 입니다.

  • 이 코드를 실행시키면 'division by zero' 라는 문자열이 출력됩니다. 5/0 에서 ZeroDivisionError 가 NameError 보다 먼저 발생하기 때문입니다.



예외처리 - 오류 회피하기 

  • 예외처리를 하다보면 오류를 자유자재로 다뤄야 합니다. 어떤 경우에는 에러를 무시하기도 하고 어떤 경우에는 프로그램의 목적에 맞게 에러를 일부러 발생시키기도 하고, 어떤 경우에는 새로운 에러를 만들어 프로그램에 적용해야 하는 경우도 있습니다.

  • 먼저 오류를 회피하는 방법을 살펴보겠습니다.

try:
print(5/0)
print(c)
except NameError as e:
print(e)
except ZeroDivisionError as e:
pass

  • 이 경우에는 어떤 상황이 발생할까요. 결과를 먼저 말하자면 어떤 것도 출력되지 않습니다. 5/0 에서 ZeroDivisionError 가 발생하면 그냥 아무작업도 하지 않고 다음으로 넘겨버립니다. 



예외처리 - 오류 발생시키기 

  • 프로그램에서 입력을 받는 경우에 목적에 맞게 입력을 받아야 할 경우가 있습니다. 예를 들어 나이를 입력받는다면 0보다 작으면 안되는 것 처럼 문법상에는 오류가 없지만 오류가 필요한 경우 오류를 일부러 발생시킬 수 있습니다.

try:
    age = int(input())
    if age < 0:
        raise NotImplementedError
    print(age)
except NotImplementedError:
    print('NotImplementedError')

  • age 를 입력받은 뒤 값 검사를 하는데 0 보다 작은 값일 경우 NotImplementedError 를 발생시킵니다. ( NotImplementedError 는 아직 작성되지 않은 에러를 의미합니다. ) 

  • age 에 -1 을 입력하면 NotImplementedError 가 출력되고 10 처럼 0 보다 큰 수를 입력하면 10 이 출력되는 코드입니다.



예외처리 - 사용자 정의 오류 

  • 예외를 원하는 경우에 발생시키는 것이 가능하다면 당연히 예외를 원하는 대로 작성하는 것도 가능합니다. 사용자 정의 오류는 파이썬의 Exception 클래스를 상속해서 만들 수 있습니다.

class AgeError(Exception):
    def __init__(self, msg='init_error_msg'):
        self.msg = msg

    def __str__(self):
        return self.msg


age = int(input())
if age < 0:
    raise AgeError('r_error_msg')
print(age)

  • AgeError 사용자 정의 오류를 만든 코드 입니다. __init__ 함수는 에러 클래스가 생성될 때 실행되는 함수로 msg 의 내용을 지정합니다. 만약 에러 발생할 때 에러메시지를 지정해주지 않는다면 'init_error_msg' 라고 지정됩니다. __str__ 함수는 에러발생했을 때 출력해주는 메시지를 리턴해주는 함수 입니다. 초기화 할때 'init_error_msg' 로 초기화 하기 때문에 에러 발생 시 다른 문자열을 정해주지 않는다면 'init_error_msg' 문자열이 출력됩니다.

  • 이 코드의 경우 AgeError('r_error_msg') 로 에러 발생 시 'r_error_msg' 문자열을 전달해 주었습니다. 따라서 AgeError 가 발생할 경우에는 'init_error_msg' 가 아닌 'r_error_msg' 가 출력될 것입니다.







부족한 블로그에 방문해 주셔서 감사합니다.

잘못된 부분이나 질문이 있으시면 

댓글로 말씀해주세요.


금방 확인하고 피드백 드리겠습니다.


좋은 하루 되세요. ^^








댓글4

  • 대구 올빼미 2019.08.07 09:22 신고

    와 한눈에 볼 수 있게 정리해주셔서 감사합니다 :) !! 큰 도움이 되었습니다.
    답글

    • Gom Guard 2019.08.07 09:24 신고

      대구 올빼미님 안녕하세요. ^^

      도움이 되었다니 저도 기분이 좋네요. ㅎㅎ

      아침부터 좋은 기운 주셔서 감사합니다.

      즐거운 하루 보내세요~

  • Frank 2019.10.08 15:26

    python 예외처리 잘 배웠습니다.
    정리가 잘되어 있어서 따라가면서
    어렵지 않게 이해할 수 있었습니다.
    고맙습니다~
    답글

  • dd 2020.05.18 11:30

    안녕하세요 ! 이해가 잘되게 설명을 잘하시는 것 같아요
    하나 궁금한게 생겼는데요!
    예시를 들어주셨던 ZeroDivisionError처럼 원하는 오류의 예외처리를 하기 위해서
    오류명을 except 다음에 선언하셨는데요
    모든 오류명이 except이 가능한가요??
    갑자기 궁금해져서요 ㅎㅎ
    답글