아무리 능력있는 개발자라도 코딩의 오류는 항상 있습니다. 이 포스팅에서는 파이썬에서 제공하는 예외처리를 사용하는 방법을 알아보겠습니다.
파이썬이던 다른 언어든지 코딩을 하다보면 예상치 못한 곳에서 오류가 생기는 경우가 있습니다. 런타임 오류가 그중 한가지 부류의 오류이죠. 런타임 오류는 코딩을 하면서 나는 오류가 아니고 프로그램이 작동되면서 나는 오류이므로 예외 처리를 하지않으면 모르고 프로그램은 항상 문제가 생기게 됩니다.
아무리 능력이 있는 개발자라도 유저의 행동이나 입력의 패턴, 값등의 모든 것을 다 알고 코딩을 하지 않으면 유저가 프로그램을 사용하는 동안에 개발자가 생각지 못한 곳에서 오류가 생길 수 있게 마련입니다.
이런 것을 대비하여 모든 개발 언어에는 예외처리 기능이 있습니다. 예외처리를 하지 않으면 디버깅시에 아주 곤란한 경우가 생기고 버그를 찾아내기가 어렵습니다.
이 포스팅은 파이썬 코드를 이용하여 예외처리하는 방법을 알아보겠습니다.
우선 아래의 간단한 예제를 보겠습니다.
파이썬으로 100을 0으로 나누는 코드를 작성하겠습니다. 0으로 나누는 산수는 코딩시에 오류로 잡히지 않죠. 하지만 런타임에는 오류가 생기게 됩니다.
이 코드를 작동하면 다음의 런타임 오류가 나게됩니다.
이럴 때는 어떻게 코드를 작성해야 할까요? 예외처리 (exception handling)를 해야합니다.
파이썬이나 다른 언어들에는 아주 많은 예외가 있습니다. 파이썬에서는 이런 예외들을 with_traceback, ArithmeticError, BufferError 와 LookupError 같은 베이스 클래스와 AssertionError, AttributeError, EOFError, ImportError 와 ZeroDivisionError 같은 콘크리트 예외 (concrete exceptions)의 카테고리로 나누고 있습니다. 파이썬의 예외처리에 관한 정보는 아래의 링크를 참조하세요.
파이썬의 문서 - 예외처리 https://docs.python.org/ko/3/tutorial/errors.html
파이썬에서 예외처리하는 방법
파이썬의 예외처리에는 아래 네가지의 프라이머리 타입이 있습니다:
Try: 삽입된 코드 블록을 실행하여본다 (try)
Except: 실행시에 예외 (exception)가 생기면 이 블록의 코드를 실행한다
Else: 예외가 없다면 (else) 이 블록의 코드를 실행한다
Finally: 마지막에는 (finally) 항상 이 블록의 코드를 실행한다
다르게 말하자면 예외처리 코드는 try (A) except (B) else (C) finally (D) 의 흐름이 됩니다 -> B의 케이스를 제외하고 A를 실행하여 문제없으면 C를 실행하고 마지막에는 D에서 마친다.
예외처리시에는 네가지의 모든 타입을 사용하지 않아도 됩니다. 보통 TRY와 EXCEPT를 많이 사용합니다.
오늘은 TRY와 EXCEPT에 관하여 알아보겠습니다.
예외처리의 장점은 유저가 잘못된 값을 입력하게 되면 피드백으로 알려 줄 수 있는 점입니다. 위의 0으로 나누는 코드 블록 예제에서 유용하게 사용이 될 수 있죠. except의 코드 블록을 사용하여 피드백을 줄 수 있게 됩니다.
위의 예제와 ZeroDivisionError라는 콘크리트 예외 타입을 사용하여 예외처리를 해 보겠습니다.
첫번째 코드라인은 다음과 같습니다.
위의 첫 라인은 파이썬에게 try의 아래 코드블록을 실행해보라는 명령을 합니다
try의 아래 코드 블록은 위 예제의 나누기 코드 블록입니다. try에 의하여 예제의 코드가 실행이 되지만 예외 상황을 모니터하게 되는거죠. 이 예제의 오류 상황은 0으로 나뉘는 상황이므로 파이썬은 b가 0으로 입력이 되는 시에만 ZeroDivisionError 예외타입을 리턴하게 됩니다.
이 예제는 다음의 커맨드로 exception.py 이름의 코드 파일을 작성합니다
이 파일에 다음의 예제 코드를 작성합니다.
저장을 하고 파일을 닫습니다. 그리고 다음의 커맨드로 저장된 파일을 실행합니다.
a에 90과 b에 0을 입력하면 다음과 같은 출력이 됩니다.
다음에는 a와 b에 90과 9를 입력하겠습니다. 그러면 다음과 같은 출력이 됩니다.
그렇다면 만약에 숫자대신 글자가 입력이 되면 어떻게 될까요? 이럴 시에는 예외처리를 어떻게 하면 될까요?
이런 경우에는 ValueError라는 예외타입이 존재합니다. 다음과 같은 코드를 작성하면 예외처리가 가능하죠.
위의 코드를 exception.py의 파일의 끝에 삽입하고 저장합니다. 숫자 90을 a에 넣고 글자 a를 b에 넣으면 다음과 같은 출력이 됩니다.
Exception as e
예외처리는 위와 같이 타입으로 나눠서 처리하는 경우도 있지만 간단하게 모든 예외를 e로 저장하여 사용하기도 합니다. 배열 (array)에서 배열의 개수 보다 많은 수의 위치를 입력하게 되면 IndexError라는 런타임 오류가 생기게 됩니다. 이 오류를 예제로 사용해 보겠습니다.
우선 네가지의 컬러가 존재하는 colors라는 배열을 생성합니다.
대부분의 개발언어도 그렇듯이 배열은 0이라는 인덱스 (index) 부터 시작합니다. 그래서 다음과 같은 배열내 주소가 생기게 되죠.
red = 0
blue = 1
yellow = 2
green = 3
4라는 인덱스를 이용하여 배열내 다섯번째 (0부터 시작이니 4는 다섯번째이죠)를 print하라는 코드를 작성하면 런타임 오류가 나게됩니다. 아래의 예제에서 실행하여 보겠습니다.
우선 colors.py라는 파일을 생성하여 다음과 같은 예제 코드를 작성합니다.
위의 프로그램을 실행하면 다음과 같은 오류가 출력이 됩니다.
출력된 오류는 프로그램을 사용하는 유저에게 도움이 되질 않죠.
같은 프로그램에 다음과 같은 예외처리를 하겠습니다:
파일을 저장하고 실행하면 다음과 같은 출력이 나옵니다:
위의 메시지는 더 이해하기가 쉽죠?
여기에서 e라는 변수는 다른 exception이므로 e를 사용하였지만 다른 이름으로도 가능합니다.
게다가 e에 현재 코드 런타임의 예외 정보가 저장이 되므로 디버깅시에는 print(e)를 사용하면 예외의 정보를 출력할 수 있습니다. 당연히 유저가 사용하는 릴리즈 버전에서는 사용하면 좋지 않으므로 print를 사용하여 출력하는 것보다 이메일이나 로그로 보내는 것이 더 좋은 방법이죠.
참고: