프로그래밍 언어를 배울 때에는 직접 따라해보고, 만들어보는 것이 중요합니다. 여러분도 지금까지 함께 공부하면서 연습을 많이 해보셨겠죠? 그렇다면 아래와 같은 메시지도 많이 보셨을 것 같네요.
>>> print hi~ File "<stdin>", line 1 print hi~ ^ SyntaxError: invalid syntax
위에선 'hi~'라는 문자열을 출력하려고 했는데, 뭔가 문제가 생긴 것 같죠? 메시지가 난해한 것 같은데… 무슨 뜻인지 해독을 해볼까요?
File "<stdin>", line 1
파일의 1번째 줄에서
print hi~
^
^로 표시된 부분에
SyntaxError: invalid syntax
잘못된 구문으로 인해 오류가 발생했음
한마디로 문법이 틀렸다는 얘기군요. 여기서 이라는 건 표준 입력(standard input), 즉 키보드를 통해 입력되는 것을 뜻합니다. 대화식으로 작성하지 않고 파일로 작성해서 실행시켰다면 그 파일의 이름이 나왔겠지요.
이렇게 파이썬은 프로그램 실행 중에 문제가 생기면, 어디가 어떻게 잘못됐는지 판단해서 우리에게 알려줍니다. 그러면 우리는 그 부분을 수정해서 잘 작동하도록 하면 되지요.
그런데, 프로그램을 짜다보면 평소에는 잘 돌아가다가 가끔씩 문제가 생기는 경우도 있답니다. 다음의 예제가 바로 그런 경우인데요, 두 수를 곱하고 나눠서 더하는 함수입니다.
>>> def f(a, b): ... return (a * b) + (a / b) ... >>> f(4,2) 10
아직은 별다른 문제가 없어보이죠? 하지만 두 번째 인자로 0을 넘겨주면 난리가 납니다.
>>> f(3,0) Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 2, in f ZeroDivisionError: integer division or modulo by zero
정수를 0으로 나누는 오류가 발생했다고 하는군요. 원래 숫자를 0으로 나눌 수가 없죠? 그렇다면 이 함수는 손을 좀 봐야겠네요.
>>> def f(a, b): ... if a and b: ... return (a * b) + (a / b) ... elif a: ... return 'unable' ... else: ... return 'undefined' ...
이제 좀 그럴 듯 하네요.
>>> f(3, 0) 'unable' >>> f(0, 0) 'undefined'
OX퀴즈!! 이제 이 함수는 더 이상 오류가 생길 일이 없겠죠?
그렇다구요?
과연 그럴까요…
f(300000, 500000)
를 한번 실행시켜보세요.
계산 결과가 잘 나올 수도 있지만,
>>> f(300000, 500000) 150000000000.6
파이썬 버전이 낮을 경우 아래와 같이 오류가 발생하기도 합니다.
>>> f(300000, 500000) Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 3, in f OverflowError: integer multiplication
인자로 받은 두 수의 곱이 정수형으로 처리하기에는 너무 큰 값이라서 오류가 발생했군요.
>>> f(twenty, five) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'twenty' is not defined
프로그램을 작성하다 보면 오류가 발생할 수 있는 경우는 끝도 없습니다. 우리가 이런 오류를 모두 예상해서 프로그램을 작성한다는 것은 정말로 '삽질'이라고 밖에 할 수 없겠네요. 앞의 예에서 불능과 부정을 정해준 것은 나쁘지 않다고 하더라도, 다른 두 경우까지 각각 처리해주는 건 시간 낭비이겠죠?
다행히 파이썬에선 이런 문제를 쉽게 해결하는 방법이 있습니다. 위와 같이 프로그래머의 의도와 동떨어진 상황이 발생하는 것을 예외(exception)라고 해서, 예외가 발생하면 어떤 조치를 취할 것인지 정해주는 것이죠.
그럼 예외를 처리할 수 있도록 함수를 수정해 보도록 하지요.
>>> def f(a, b): ... try: ... if a and b: ... return (a * b) + (a / b) ... elif a: ... return 'unable' ... else: ... return 'undefined' ... except: ... return 'try again'
보시는 것처럼 방법은 간단합니다. 기본적인 문장들을 try 밑에 넣어주고, 예외가 발생했을 때 처리할 부분은 except 밑에 넣어주면 됩니다. 일단 시도(try)해 보다가 문제가 생기면(except) 처리해 주는 것이죠.
예외는 오류(error)보다 더 넓은 개념이긴 하지만 지금은 비슷하게 생각하셔도 되구요, C++과 Java에서도 비슷하게 사용된답니다.
위의 예제는 예외가 무엇인지 설명하기 위해 간단히 작성한 것이니 참고만 하시기 바랍니다. 예외가 발생하지 않도록 막는 것이 능사가 아니라, 필요한 곳에서 적절한 예외를 발생시킬 수 있도록 궁리를 많이 해야 합니다.