'Python Built-in Exceptions Hierarchy'에 해당되는 글 1건

  1. 2019.08.08 [Python Exceptions] try, except, else, finally 절을 이용한 Python Programming 예외 처리

Python 으로 프로그래밍을 하다보면 의도했던, 의도하지 않았던 간에 예외를 처리해야 하는 상황에 맞닥드리게 됩니다. 이때 에러를 발생(Raise Error) 시킬 수도 있고 회피할 수도 있으며, 필요에 따라서는 예외 처리를 해야 할 수도 있습니다. 


이번 포스팅에서는 Python에서 예외를 처리하는 4가지 try, except, else, finally 절(clause)을 소개하겠습니다. 




  • try 에는 정상적으로 실행할 프로그램 코드(code block) 써줍니다. 

  • except 절에는 의 try 절에서 실행한 코드에 예외가 발생했을 경우에 실행할 코드를 써줍니다. 

  • else 절에는 앞의 try 절에서 실행한 코드에 예외가 발생하지 않은 경우에 실행할 코드를 써줍니다. 

  • finally 절에는 try 절에서의 예외 발생 여부에 상관없이 항상(always execute) 마지막에 실행할 코드를 써줍니다. 


간단한 예로서, 두개의 숫자를 매개변수로 받아서 나눗셈을 하는 사용자 정의함수를 try, except, else, finally 의 예외절을 사용하여 정의해 보겠습니다. 


try, except, else, finally 절의 끝에는 콜론(:)을 붙여주며, 그 다음줄에 코드 블락은 들여쓰기(indentation)을 해줍니다. 

except의 경우 'except:' 만 사용해도 되고, 아래 예의 'except ZeorDivisionError as zero_div_err:' 처럼 Built-in Exception Class를 사용해서 에러를 명시적으로 써줄 수도 있습니다. (본문의 제일 밑에 Python Built-in Exception Class 의 계층 구조 참조)



# Python Exceptions: try, except, else, finally

def divide(x, y):

    try:

        result = x / y

    except ZeroDivisionError as zero_div_err:

        print("Except clause:", zero_div_err)

    else:

        print("Else clause: The result of division is", result)

    finally:

        print("Finally clause is executed.")

 




(1) try 절 정상 실행 시 (executed nomally): try --> else --> finally


두 숫자 x, y를 인자로 받아서 나눗셈을 하는 사용자 정의함수 divide(x, y) 에 x=1, y=2 를 넣어서 정상적으로 코드가 수행되었을 때의 결과를 보겠습니다.  마지막으로 finally 절이 실행되었습니다. 


In [1]: def divide(x, y):

   ...: try:

   ...: result = x / y

   ...: except ZeroDivisionError as zero_div_err:

   ...: print("Except clause:", zero_div_err)

   ...: else:

   ...: print("Else clause: The result of division is", result)

   ...: finally:

   ...: print("Finally clause is executed.")

   ...:

   ...:

In [2]: divide(1, 2)

Else clause: The result of division is 0.5

Finally clause is executed. 




(2) try 절 실행 중 예외 발생 시 (exception occurred): try --> except --> finally


1을 '0'으로 나누라고 하면 'except ZeroDivisionError as zero_div_err:' 의 except 절이 실행됩니다. 그리고 마지막으로 finally 절이 실행되었습니다. 


In [3]: divide(1, 0)

Except clause: division by zero

Finally clause is executed.




(3) try 절 Error 발생 시: try --> finally  --> Raise Error


divide(x, y) 사용자 정의함수에 숫자를 인자로 받는 매개변수에 문자열(string)을 입력하는 경우 TypeError가 발생하겠지요? 이때 finally를 먼저 실행하고, 그 후에 TypeError 를 발생시킵니다. 


In [4]: divide("1", "2")

Finally clause is executed.

Traceback (most recent call last):


File "<ipython-input-4-bbf78a5b43b9>", line 1, in <module>

divide("1", "2")


File "<ipython-input-1-78cbb56f9746>", line 3, in divide

result = x / y


TypeError: unsupported operand type(s) for /: 'str' and 'str'


Traceback (most recent call last):


File "<ipython-input-4-bbf78a5b43b9>", line 1, in <module>

divide("1", "2")


File "<ipython-input-1-78cbb56f9746>", line 3, in divide

result = x / y


TypeError: unsupported operand type(s) for /: 'str' and 'str' 




(4) Try Except 절에서 에러 발생 시 Exception Error 이름과 Error message 출력



import numpy as np


arr = np.array([[1., 2., 3.], [4.0, 5., 6.]])

print(arr)

[Out]
[[1. 2. 3.]
 [4. 5. 6.]]


# It will not work and eraise an error

try:

    arr.reshape(5, -1)

except Exception as e:

    print(f"{type(e).__name__}: {e}")

[Out] 
ValueError: cannot reshape array of size 6 into shape (5,newaxis)





[ 참고: The Class Hierarchy of Python Built-in Exceptions ]

(* source: https://docs.python.org/3/library/exceptions.html)


 BaseException

 +-- SystemExit

 +-- KeyboardInterrupt

 +-- GeneratorExit

 +-- Exception

      +-- StopIteration

      +-- StopAsyncIteration

      +-- ArithmeticError

      |    +-- FloatingPointError

      |    +-- OverflowError

      |    +-- ZeroDivisionError

      +-- AssertionError

      +-- AttributeError

      +-- BufferError

      +-- EOFError

      +-- ImportError

      |    +-- ModuleNotFoundError

      +-- LookupError

      |    +-- IndexError

      |    +-- KeyError

      +-- MemoryError

      +-- NameError

      |    +-- UnboundLocalError

      +-- OSError

      |    +-- BlockingIOError

      |    +-- ChildProcessError

      |    +-- ConnectionError

      |    |    +-- BrokenPipeError

      |    |    +-- ConnectionAbortedError

      |    |    +-- ConnectionRefusedError

      |    |    +-- ConnectionResetError

      |    +-- FileExistsError

      |    +-- FileNotFoundError

      |    +-- InterruptedError

      |    +-- IsADirectoryError

      |    +-- NotADirectoryError

      |    +-- PermissionError

      |    +-- ProcessLookupError

      |    +-- TimeoutError

      +-- ReferenceError

      +-- RuntimeError

      |    +-- NotImplementedError

      |    +-- RecursionError

      +-- SyntaxError

      |    +-- IndentationError

      |         +-- TabError

      +-- SystemError

      +-- TypeError

      +-- ValueError

      |    +-- UnicodeError

      |         +-- UnicodeDecodeError

      |         +-- UnicodeEncodeError

      |         +-- UnicodeTranslateError

      +-- Warning

           +-- DeprecationWarning

           +-- PendingDeprecationWarning

           +-- RuntimeWarning

           +-- SyntaxWarning

           +-- UserWarning

           +-- FutureWarning

           +-- ImportWarning

           +-- UnicodeWarning

           +-- BytesWarning

           +-- ResourceWarning



많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)



728x90
반응형
Posted by Rfriend
,