try, except, else, finally

지금까지 수업을 진행하셨다면 Python으로 프로그램을 작성하고 실행(Run)을 하는 중에 오류(Error)가 발생하는 경우를 겪어 보았을 겁니다. 보통 오류가 발생하면 어떻게 되었나요? 경험적으로 오류가 발생한 경우 프로그램 실행이 즉각적으로 정지(Stop)되는 경험을 했을 겁니다.

반면 예외(Exception)라는 것이 있습니다. 따지고 보면 예외상황이 발생했다는 것은 오류가 발생했다는 것을 의미합니다. 그러나, 이것을 예외라고 하는 것은 오류가 발생한 것을 프로그램 중단 이유로 보지 않고 별도의 처리를 하기 때문입니다. 그래서 이것을 예외라고 부르는 것이겠지요.

try, except

우선 사용되는 형식을 살펴보겠습니다.

try:
    var_input = input("숫자를 입력해 주세요\n")
    var_int = int(var_input)
    var_rst = 100/var_int
    print(var_rst)
except:
    print("Exception Raised")

위의 예제는 가장 간단한 예외처리 소스 코드입니다. 위의 코드는 크게 두 구역으로 나뉘어져 있습니다. 하나는 try 구간이고 하나는 except 구간입니다. 여기서 try 구간은 원하는 연산이 실행되는 구간입니다. 내용은 간단합니다. 그저 숫자를 입력받아서 100을 입력받은 숫자로 나눠서 출력합니다. 그런데 지금까지 배운 것을 고려하면 뭔가 이상한 것이 보일 겁니다. 무엇이 문제일까요? 우선 크게 두 개로 나뉠 수 있습니다. 하나는 숫자가 아닌 값이 입력될 경우는 어떨지하는 문제입니다. 나머지는 연산과 관련하여 숫자가 0으로 입력될 때의 문제입니다. 이미 중학교 수학에서 숫자를 0으로 나누면 무한대를 가진다는 것을 배웠을 겁니다. 그러나, 컴퓨터는 무한대를 이해하지 못합니다. 실제로는 0으로 나누려고 시도하다가 오류를 발생시킵니다.(일부 개발언어의 경우 0으로 나눌 경우 Infinite 로 표시하기도 합니다.)

프로그램을 구동시켜서 뭔가 오류를 발생시키도록 합시다. 숫자대신 알파벳이나 다른 기호를 입력해도 좋습니다. 또는 0을 입력하여 연산시의 오류를 발생시켜도 좋습니다. 어째든 오류가 발생되어 어떻게 작용되는지를 확인하십니다. 오류가 발생되면 except 구간이 실행되어 오류가 발생되었음을 알리게 됩니다. 예제는 간단히 "Exception Raised"라는 문장을 출력하도록 했습니다. 위 내용은 너무 간단하여 except 구간의 내용을 출력하여 프로그램이 종료하게 됩니다. 더 이상 뒤에 실행할 내용이 없기 때문이죠. 하지만, 예외 상황이 되었다고 일반적인 오류처럼 프로그램이 중단되지는 않습니다.

그런데 예외가 발생한 것까지는 좋은데 어떤 예외가 발생한 지는 어떻게 알 수 있을까요?

예외의 확인

try:
    var_input = input("숫자를 입력해 주세요\n")
    var_int = int(var_input)
    var_rst = 100/var_int
except Exception as e:
    print("Exception Raised")
    print(e)

이번 예제는 위의 것과 많이 비슷합니다. 다만 5행의 except 구간이 좀 다릅니다. 위와는 달리 Exception as e라른 부분이 추가되었습니다. Exception은 예외에 관련한 내용을 담는 가장 기본적인 클래스입니다. 클래스의 의미는 차후에 학습하므로 여기서는 넘어가기로 합니다. 그저 전체적인 예외를 확인하기 위해서 5행처럼 사용한다는 것만 기억하시기 바랍니다.

숫자를 입력해 주세요
0
Exception Raised
division by zero
숫자를 입력해 주세요
k
Exception Raised
invalid literal for int() with base 10: 'k'

위의 예제를 통해서 출력한 내용입니다. print(e) 를 통해서 결과를 출력했습니다. 보시는 바와 같이 어떤 오류가 발생했는지에 관한 정보를 보여주므로 이에 관한 처리를 할 수 있습니다.

여러 종류 예외의 처리

위의 예제를 보면 알겠지만, 하나의 코드 블럭에서는 다양한 오류가 발생할 수 있습니다. 앞에서 다룬 예제는 기본적으로 두 종류의 오류가 생겼다는 것을 확인했습니다. 앞에서도 잠깐 언급했지만 예외는 오류가 발생했을 때 프로그램의 중단이 아니라 그 내용에 관한 처리를 하기 위함입니다. 그런데, 코드에서 여러 종류의 예외가 발생할 수 있다면 어떻게 할 수 있을까요?

try:
    while True:
        var_input = input("숫자를 입력해 주세요\n")
        var_int = int(var_input)
        var_rst = 100/var_int
        print(var_rst)
        break
except ZeroDivisionError:
    print("Do Not input 0")
except ValueError:
    print("You must input value as numeric!")
except Exception as e:
    print("Exception Raised")
    print(e)

코드의 내용은 앞에서와 같습니다. 그런데 뭔가 except가 많죠. 이것은 여러 종류의 오류에 대해서 각각의 오류를 처리하기 위한 방법입니다. 8행과 10행 12행은 각기 다른 오류에 관해서 별도의 예외처리를 하는 구간입니다.

0을 입력하였을 경우 ZeroDivisionError가 발생하여 8행의 예외구간이 실행됩니다. 숫자대신 다른 내용이 입력된 경우 10행의 ValueError가 발생하게 되죠. 그외에 다른 오류에 대해서는 12행의 예외구간이 실행되는 것입니다. 간단한 예제이므로 그저 오류 내용만 출력하는 것이지만, 다양한 방법으로 별도의 복잡한 오류처리 코드를 각 예외 구간에 추가할 수 있습니다.

위의 예제는 while을 이용하여 예외를 구현했다는 것입니다. 입력이 숫자가 아니거나, 0인 경우 프로그램은 예외구간을 실행하고 다시 진행됩니다. 때문에 입력이 올바르지 않다면 프로그램은 오류 메시지를 출력하고 다시 한 번 입력을 기다리게 됩니다.

else

while True:
    try:
        var_input = int(input("숫자를 입력해 주세요\n"))
        var_rst = 100/var_input
    except ZeroDivisionError:
         print("Do Not input 0")
    except ValueError:
         print("You must input value as numeric!")
    except Exception as e:
         print("Exception Raised")
         print(e)
    else :
        print(var_rst)
        break

위의 예제는 앞선 예제와 많이 비슷합니다. 기능적으로는 거의 같습니다. 다만, 이 예제는 else라는 것이 포함되어 있습니다. else는 try구간에서 어떠한 예외상황이 발생하지 않았을 경우 진행되는 구간압니다. 실제로 위의 예제에서 모든 입력이 개발자가 원하는 방향으로 진행된다면 else를 출력하고 종료하게 됩니다.어떤 특정한 행위가 진행되고 예외가 발생하지 않 확실한 동작을 수행야 한다면 else 구간을 이용하면 좋습니다.

finally

while True:
    try:
        var_input = int(input("숫자를 입력해 주세요\n"))
        var_rst = 100/var_input
    except ZeroDivisionError:
         print("Do Not input 0")
         100/0
    except ValueError:
         print("You must input value as numeric!")
    except Exception as e:
         print("Exception Raised")
         print(e)
    else :
        print(var_rst)
        break
    finally:
        print("Anyway this is 'finally' section ")

이번 에는 위의 예제에서 finally 구간이 추가되었습니다. 이 구간은 else와는 다르게 예외가 발생했던 발생하지 않았던 수행되 내용입니다. 예외가 발생했더라도 전체적인 수행에 해를 끼치지 않는 어떤 동작을 수행해야 한다면 이 구간에서 수행하면 됩니다.

다만, 알아두어야 할 점은 예외구간(except), else 구, finally 구간 모두 그 안에서 다시 오류가 발생할 수 있다는 점입니다. 따라서 예외처리를 해야 한다면, 이러한 구간에서는 오류가 발생하지 않도록 코드를 잘 짜야 한다는 점입니다.

Last updated