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
,