• 2020. 7. 29.

    by. 윈썸지니

    반응형

    출처:pixabay

    이번 포스팅은 파이썬 프로그램에서 오류가 발생시 오류를 제어하는 방법에 대한 포스팅 입니다.

     

    프로그램 개발 시 오류가 발생하면 프로그램이 자동으로 중지 됩니다.

    하지만 때로는 오류가 발생해도 무시하고 넘어가거나 다른 행동을 하도록 코딩해야 하는 경우가 빈번합니다.

     

    또한 오류 발생시 로그 처리하여 오류 내용을 파악하기 위해 사용하기도 합니다.

    그리고 항상 예외 사항이 존재하므로 프로그램 개발 시 꼭 사용해야하는 것이 예외 처리 입니다.

    중요한 내용이니 잘 사용해 봅니다.

     

    파이썬에서는 예외 처리 구문이 아래와 같습니다.

    try:
        수행할 문장

    except:
        예외(오류) 발생시 수행할 문장

    else:
        예외(오류)가 발생하지 않았을 때 수행할 문장 -> 필요한 경우 사용

    finally:
        항상 마지막에 수행할 문장 -> 오류와 상관없이 실행 -> 필요한 경우 사용

     

    먼저 오류를 발생시키는 예제 입니다.

    아래 예제는 날자 형식을 맞이 않게 입력하여 날짜 타입으로 변경하는 과정에서 오류를 발생시킵니다.

     

    IDLE shell 창을 실행 합니다.

    >>> from datetime import datetime       # 날짜 관련된 모듈을 import 합니다.

    >>> dtval = input( '시간 입력:YYYY-MM-DD.hh:mm:ss ‘ )     # 시간을 25시로 입력하여 오류를 발생 시킵니다.

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020-05-05.25:00:00

    >>> datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S’ )      # 위의 변수를 시간 형식으로 변경의 경우 25시는 없으므로 ValueError 가 발생합니다.

    Traceback (most recent call last):

      File "<pyshell#11>", line 1, in <module>

        datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S' )

      File "C:\Users\hyejin\AppData\Local\Programs\Python\Python38\lib\_strptime.py", line 568, in _strptime_datetime

        tt, fraction, gmtoff_fraction = _strptime(data_string, format)

      File "C:\Users\hyejin\AppData\Local\Programs\Python\Python38\lib\_strptime.py", line 349, in _strptime

        raise ValueError("time data %r does not match format %r" %

    ValueError: time data '2020-05-05.25:00:00' does not match format '%Y-%m-%d.%H:%M:%S'

     

    위의 예제를 오류를 처리하기 위해 예외처리를 합니다.

    다음 예제는 try, except 만 처리하는 예제 입니다.

    >>> from datetime import datetime

    >>> dtval = input( '시간 입력:YYYY-MM-DD.hh:mm:ss ' )

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020-05-05.23:00:00               # 정상 입력을 하여 동작을 확인합니다.

    >>> try:

        stime = datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S' )

        print("입력일자:%s" % dtval )

    except:

        print("날짜 형식이 맞지 않습니다.")


    입력일자:2020-05-05.23:00:00                     # 오류가 발생하지 않아  정상 출력을 합니다.

    >>> dtval = input( 시간 입력:YYYY-MM-DD.hh:mm:ss )

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020-05-05.25:00:00         # 오류를 발생 시키려고 25시를 입력합니다.

    >>> try:

        stime = datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S' )

        print("입력일자:%s" % dtval )

    except:

        print("날짜 형식이 맞지 않습니다.")

       

    날짜 형식이 맞지 않습니다.                        # 오류 발생으로 except 구문을 실행합니다.

    >>>

     

    위의  예제를 잘 관찰하면 try 구문을 순차적으로 수행하다 오류가 발생하면 아래 구문을 수행하지 않고 바로 except 구문으로 분기합니다. 그래서 오류 발생시 try 구문에 있는 입력일자를 출력해 주는 print 구문을 수행하지 않았습니다.

     

    다음 예제는 except 구문에서 여러가지 다양한 오류가 발생할 수 있습니다. 

    특정한 오류만 예외 처리하는 예시 입니다.

    다음 예제 부터는  shell 창에서 하지 않고 좀더 보기 좋게 파일로 저장하여 실행하는 방법으로 보여드립니다.

     

    특정 오류만 처리하는 예제 ( error_test.py )

    from datetime import datetime

    dtval = input( '시간 입력:YYYY-MM-DD.hh:mm:ss ' )

    try:

        stime = datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S' )

        print("입력일자:%s" % dtval )

    except ValueError:

        print("날짜 형식이 맞지 않습니다.")

     

    위의 예제를 실행해 보겠습니다.

    명령창(CMD ) 를 실행하여 py 파일을 저장한 위치로 이동하여 실행합니다.

    C:\py_test>python error_test.py

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020-05-05.25:00:00

    날짜 형식이 맞지 않습니다.

    같은 결과가 나왔습니다.  

     

    다른 오류를 발생시키기 위해서 위의 코드에서 맨 처음 문장을 comment 처리합니다.

    #from datetime import datetime

    다시 실행해 봅니다.

    오류가 ValueError 이 아니기 때문에 화면상에 오류를 출력하고 프로그램은 중지 합니다.

    C:\py_test>python error_test.py

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020-05-05.25:00:00

    Traceback (most recent call last):

      File "error_test.py", line 6, in <module>

        stime = datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S' )

    NameError: name 'datetime' is not defined

     

    위의 예제에서 다시 특정 오류만 예외 처리하는 ValueError를 삭제하고 파일을 다시 저장합니다.

    #from datetime import datetime

    dtval = input( '시간 입력:YYYY-MM-DD.hh:mm:ss ' )

    try:

        stime = datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S' )

        print("입력일자:%s" % dtval )

    except :

    #except ValueError:

        print("날짜 형식이 맞지 않습니다.")

    다시 실행해 봅니다. 이번에는 날짜 형식에 맞게 입력합니다.

    오류가 나지 말아야 하는데 from 을 막았기 때문에 datetime 모듈이 없어서 발생한 오류이나 except 만 했으므로 모든 오류가 except 구문을 수행하므로 날짜형식이 맞지 않다는 메시지를 출력합니다.

     

    다음 예제에서 이를 더 보강합니다.

    C:\py_test>python error_test.py

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020-05-05.23:00:00

    날짜 형식이 맞지 않습니다.

     

    아래 예제와 같이 코드를 보강해 주세요.

    #from datetime import datetime

    dtval = input( '시간 입력:YYYY-MM-DD.hh:mm:ss ' )

    try:

        stime = datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S' )

        print("입력일자:%s" % dtval )

    except ValueError :

        print("날짜 형식이 맞지 않습니다.")

    except Exception as err:

        print( err )

     

    다시 명령창에서 실행해 봅니다.

    이번에도 일자는 정상 입력을 합니다.

    C:\py_test>python error_test.py

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020-05-05.23:00:00

    name 'datetime' is not defined

    위의 예제를 실행하면 일자는 정상 입력이 되었으므로 ValueError 오류는 아닙니다.

    따라서 두번째 except 구문을 수행한 것입니다.

     

    두번째 except 구문을 보면 Exception 이라고 되어 있는 것은 오류 코드를 모를 경우 또는 모든 발생하는 오류를 처리하고 싶을 경우 사용합니다.

    또한 as 변수 를 사용하여 변수에 오류 내용을 받아서 출력해 주거나 다른 로그 파일등에 저장하기 위해 변수로도 입력 받을 수 있습니다.

     

    위의 예제를 보면 만약 일자를 형식에 맞지 않게 입력하면 except 구문이 둘 다 해당되기 때문에 둘 다 실행하는 것이 아닌 것인가? 하는 의문을 품을 수 있는데 먼저 해당되는 except 만 처리 합니다.

    따라서 Exception 을 처리 하는 것은 except 중 맨 마지막에 써 주어야 합니다.

    위의 예제 순서를 바꾸면 항상 Exception 이 먼저 해당되므로 항상 Exception 구문만 실행이 되겠지요?

     

    참고로 위의 형식이 일자 형식이 안 맞는 경우를 테스트 하고 싶을 경우는 맨 처음 문장의 comment(#) 을 제거해 주세요.

    일자 형식을 체크하기 전에 datetime 모듈이 없다는 오류가 먼저 발생하기 때문이지요.

     

    이제 else finally 를 사용하는 예제를 해 봅니다

    .

    그동안 예제를 아래와 같이 코드를 추가해 주세요.

    from datetime import datetime

    dtval = input( '시간 입력:YYYY-MM-DD.hh:mm:ss ' )

    try:

        stime = datetime.strptime( dtval, '%Y-%m-%d.%H:%M:%S' )

        print("입력일자:%s" % dtval )

    except Exception as err:

        print( err )

    except ValueError as err:

        print("날짜 형식이 맞지 않습니다.")

        print(err)

    else:

        print("오류가 발생하지 않았습니다")

    finally:

        print("오류 상관없이 맨 마지막에 실행합니다.“ )

     

    명령창에서 실행해 봅니다.

    정상 입력해 봅니다.

    C:\py_test>python error_test.py

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020-05-05.23:00:00

    입력일자:2020-05-05.23:00:00

    오류가 발생하지 않았습니다

    오류 상관없이 맨 마지막에 실행합니다.

    위의 결과에서 else 구문은 오류가 발생하지 않았을 경우 사용됩니다.

    finally 구문은 항상 실행됩니다.

     

    오류를 발생시키기 위해 일자를 년도만 입력해 봅니다.

    C:\py_test>python error_test.py

    시간 입력:YYYY-MM-DD.hh:mm:ss 2020

    time data ‘2020’ does not match format ‘%Y-%m-%d.%H:%M:%S’

    오류 상관없이 맨 마지막에 실행합니다.

    위의 결과에서 오류가 발생 했으므로 else 구문은 실행되지 않았으며, 항상 실행되는 finally 구문은 실행되었습니다.

    finally file 처리에서 open 하고 close 를 꼭 해야 하므로 오류가 발생해도 파일이 close 될 수 있도록 close() 등을 사용하면 좋습니다.

     

    이상으로 예외처리에 대한 기본 기능을 알아보았습니다.

    다음 포스팅은 예외를 일부러 발생하거나 그냥 무시하는 방법에 대해 포스팅 예정 입니다.

    반응형