ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파이썬의 예외처리
    Python/study 2013. 12. 18. 03:26

    ※ 주의사항

    아래 공격 코드는 연구 목적으로 작성된 것이며, 허가 받지 않은 공간에서는 테스트를 절대 금지합니다.

    악의 적인 목적으로 이용할 시 발생할 수 있는 법적 책임은 자신한테 있습니다. 이는 해당 글을 열람할 때 동의하였다는 것을 의미합니다.

    해당 문서의 저작권은 해당 저자에게 모두 있습니다. 다른 용도로 사용할 시 법적 조치가 가해질 수 있습니다.


    이번에는 예외처리에 대하여 알아보도록 하겠습니다. 


    예외라는 것은 무엇일까요? 단어 뜻 그대로 일반적인 것에서 벗어나는 일이나 상황을 말하는 것입니다. 다시 말해서 정상적인 동작을 하지 못하는 것입니다. 이런 예외상황을 제어할 수 있도록 하는 것이 바로 예외처리입니다.


    예외처리를 하지 않은 프로그램은 예외 발생시에 당황을 하게되고, 결과적으로 프로그램의 흐름이 멈춘다던지의 악영향을 받게됩니다. 예외를 처리한다는 것은 이렇게 발생하는 예외를 제어해서 프로그램의 흐름이 유지될 수 있도록 하는 것입니다. 그러면 바로 예를 통해 알아보도록 하겠습니다.


    간단하게 산술연산을 하는 과정을 보도록 하겠습니다.


    위 예제에서는 두 가지 산술 연산을 실행하였습니다. 먼저 첫 번째 산술 연산을 보도록 하겠습니다.

    >>> 2 + (100/5)
    22
    첫 번째 산술 연산은 아주 간단합니다. 간단하게 더하기와 나누기 연산으로 이루어져 있으며 그 결과값이 정확하게 출력되는 것을 확인할 수 있습니다. 문제는 다음입니다. 다음 산술 연산을 보도록 하겠습니다.

    >>> 2 + (100/0)
    Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
    ZeroDivisionError: Integer division or modulo by zero
    첫 번째 산술 연산과 똑같이 더하기와 나누기로 이루어진 연산입니다. 하지만 그 결과 출력되지 않고 많은 문구들이 출력되었습니다. 어떤 이유로 위와 같은 결과가 나왔을 까요? 그 이유는 바로 '0' 입니다. 위의 연산식에서 정수를 '0'으로 나누려고 했기 때문에 에러가 발생한 것입니다. 

    위와 같이 에러가 발생하는 것을 예외가 발생했다고 할 수 있습니다. 일반적으로 정수를 '0'으로 나누는 것은 불가능하기 때문입니다. 따라서 파이썬은 정수를 '0'으로 나눌 것이라는 것은 예상하지 못했고, 파이썬의 입장에서는 프로그래머가 지시한 정수를 '0'으로 나눈다는 동작이 예외상황이 되는 것입니다. 위의 경우에는 해당 예외에 대한 처리 동작이 정해져 있지 않기 때문에, 에러에 대한 정보를 출력하고 프로그램이 멈췄습니다.

    정리 66) 예외 발생 : 일반적이지 않은 동작을 수행하려고 할 때, 예외가 발생합니다.

    자, 이번에는 다음 예제를 보도록 하겠습니다.
    앞서 보았던 예제는 단 하나의 명령을 수행하면서 예외가 발생하는 것을 확인했습니다. 하지만, 이번 예제에서는 프로그램이 정상적으로 동작하고 있던 중에 예외가 발생하면 어떤 결과가 나타나는지를 알아보도록 하겠습니다.


    >>> def div_loop(a, b):
    . . .      for n in range(a, b+1):
    . . .               result = 10/n
    . . .               print result
    . . .
    >>>
    먼저 함수를 하나 만들었습니다. 파라미터로 두 숫자를 받습니다. 이 숫자들을 정수 n의 범위가 되며, 함수 내에서는 정수 '10'을 n으로 나눈 몫을 출력하는 동작을 합니다. 간단한 함수죠.

    >>> div_loop(1, 3)
    10
    5
    3
    >>>

    첫 번째로 함수를 동작하면서 범위를 1부터 3까지 주어, 10을 1, 2, 3으로 순차적으로 나누도록 하였습니다. 그 결과 10, 5, 3 순으로 올바른 결과 값이 출력되는 것을 확인할 수 있었습니다.

     

    >>> div_loop(0, 4)

    Traceback (most recent call last):

       File "<stdin>", line 1, in <module>

       File "<stdin>", line 3, in div_loop

    ZeroDivisionError: integer division or modulo by zero

    다음은 나누는 값을 범위를 0부터 4까지를 주었습니다. 즉, 10을 0, 1, 2, 3, 4로 순차적으로 나누게 한 것입니다. 그 결과 곧바로 정수를 '0'으로 나누려했다는 의미의 ZeroDivisionError가 발생하였습니다. 맨 처음에 '0'으로 10을 나누려고 했기 때문입니다. 

     

    그런데 문제는 이것 뿐만이 아닙니다. 첫 번째 동작에서 10을 '0'으로 나누려했기 때문에 에러가 발생한 것은 당연한 일이나, 그 다음에 동작해야하는 10을 1, 2, 3, 4로 순차적으로 나누는 일은 정상적인 동작이지만 아예 실행조차 되잔 않고 프로그램이 종료되었습니다. 첫 번째에 나온 '0' 때문에 그 뒤에 있는 나머지 정상적인 작업이 하나도 수행되지 못한 것입니다.

     

    정리 67) 예외 발생의 문제점 : 예외가 발생하면 예외가 발생한 시점에 프로그램이 종료됩니다.

     

    이것이 바로 예외처리를 하지 않았을 경우에 발생하는 문제점입니다. 그럼 이어서 예외처리를 했을 때에는 어떤 결과가 나타나는지 알아보도록 하겠습니다.


     

    위의 예에서 선언한 함수는 이전에서 사용한 함수와 같습니다. 다만, for문 안에 동작하는 구문에서 추가된 부분이 있습니다. 


    try:

    result = 10/n

    print result

    except ZeroDivisionError as e:

    print "Don't do it"

    위에 보이는 구문이 바로 예외처리의 핵심인 try, except 구문입니다. try 구문은 예외가 발생하지 않은 경우 즉, 일반적인 상황에서 동작할 명령을 포함하고 있습니다. 일단 시도하는 것이죠. try라는 단어가 '시도하다'라는 뜻을 가지고 있지 않습니까? :-) 


    정리 68) try 구문 : try 구문은 일반적인 상황에서 동작할 명령을 포함합니다.


    이어서 나오는 except 구문은 try 구문에 포함된 명령을 수행하다 예외가 발생했을 때 수행하게 될 명령을 포함하고 있습니다. 여기서는 정수 10을 n이라는 값으로 나누는 연산을 합니다. 아무런 문제가 없을 경우에는 try 문에 포함된 것 처럼 나누기 연산한 결과를 result라는 공간에 저장하고, 해당 값을 출력합니다.


    그러나 정수 10을 n으로 나눌 때, n이라는 값이 '0'일 경우에는 앞서 보았던 ZeroDivisionError 가 발생하게 됩니다. 이때 except 문에 걸리게 되어 try문이 아닌, except 문에 포함된 명령을 수행하는 것입니다. 결과적으로 n 값이 '0'으로 주어져 정수 10을 '0'으로 나누려고 하면 except 문이 포함하고 있는 명령인 print "Don't do it" 이라는 명령을 수행하게 되는 것입니다.


    정리 69) except 구문: except 구문은 예외가 발생한 상황에서 동작할 명령을 포함합니다.


    그리고 여기서 눈여겨 볼 한 가지가 있습니다. 예외가 발생한 이후에도 정상적으로 프로그램이 동작한다는 것입니다. 위의 예제에서 볼 수 있듯이 예외가 발생해서 예외처리로 Don't do it 이라는 문자열이 출력된 이후에도 함수가 정상적으로 동작하여 결과 값들이 출력된 것을 확인할 수 있습니다. 이렇게 예외처리를 하게되면, 예기치않은 예외가 발생한 경우에 문제가 되는 예외는 따로 처리를 하고, 나머지 동작들은 정상적으로 수행합니다. 따라서 프로그램의 흐름이 끊기지 않고 끝까지 진행될 수 있는 것입니다.


    위의 예제에서는 정수를 '0'으로 나눌 때 발생하는 ZeroDivisionError이라는 예외사항만을 콕 집어서 예외처리하였지만, 다음과 같이 예외가 발생하였을 경우에 간단하게 예외를 처리할 수 있는 방법도 있습니다.



    예외처리를 잘 할수록 프로그램의 질과 성능이 높아집니다. 예외가 발생할 수 있다고 예측되는 부분에서 예외처리를 잘해둔다면, 좋은 프로그램을 작성하는 데에 아주 큰 도움이 될 것입니다. :-)


    정리모음

    정리 66) 예외 발생 : 일반적이지 않은 동작을 수행하려고 할 때, 예외가 발생합니다.
    정리 67) 예외 발생의 문제점 : 예외가 발생하면 예외가 발생한 시점에 프로그램이 종료됩니다.
    정리 68) try 구문 : try 구문은 일반적인 상황에서 동작할 명령을 포함합니다.

    정리 69) except 구문: except 구문은 예외가 발생한 상황에서 동작할 명령을 포함합니다.

     

    참고 URL 및 도서

    - 파이썬 완벽 가이드, 데이비드 M. 비즐리 저, 2012년, 인사이트 펴냄


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

    파이썬의 모듈  (0) 2013.12.18
    파이썬의 객체와 클래스  (0) 2013.12.18
    파이썬의 코루틴  (2) 2013.12.18
    파이썬의 제네레이터(추가)  (0) 2013.12.18
    파이썬의 제네레이터와 이더레이터  (8) 2013.12.18
    파이썬의 함수  (0) 2013.12.18
    파이썬의 반복문  (0) 2013.12.18
    파이썬의 파일 입출력  (0) 2013.12.18
    파이썬의 조건문  (0) 2013.12.18
    파이썬의 자료형 - 사전  (0) 2013.12.18
Designed by Tistory.