프로그래밍을 하다 보면 많은 에러들을 만나게 됩니다.
이 에러들은 다양한 이유로 발생하며, 한 번 에러가 발생하면 프로그램이 종료되기 때문에 그 이후의 코드들은 실행되지 않습니다. 따라서 예측 가능한 에러들은 예외 처리(error handling)를 통해서 오류가 발생하더라도 코드가 계속 진행되게 합니다.
이번 시간에는 이 예외 처리에 대해 알아보겠습니다.
예외 처리는 주로 try-except 문법을 통해 이루어집니다. try-except 문법은 다음과 같은 구조를 가지고 있습니다.
try:
...
except (에러명):
...
try 내의 코드 중에서 에러명에 해당되는 에러가 발생한다면, except 내의 코드를 실행합니다. 이때 에러명은 있을 수도, 없을 수도 있으며 없을 때는 try 내에서 발생한 모든 에러에 대해 except 내 코드가 실행됩니다.
코드를 통해 살펴보면 다음과 같습니다.
try:
print(1 - 'a') # int와 str은 뺄 수 없으므로 에러가 발생합니다.
except TypeError:
print("오류입니다.")
1-'a'
를 실행해보면, TypeError
가 발생하기 때문에 except에 지정하여 예외 처리를 할 수 있습니다.
에러명을 적지 않을 때에도 모든 에러에 대해 처리하기에 위 코드와 동일한 결과가 나옵니다.
try:
print(1 - 'a')
except:
print("오류입니다.")
# 결과
# 오류입니다.
try-except 문법은 에러명 뒤에 as를 사용하여 에러 메세지를 출력할 수 있습니다. 즉, 에러의 정확한 내용을 알 수 있죠.
try:
print(3 / 0) # 0으로 나눴으므로 에러가 발생합니다.
except ZeroDivisionError as e:
print(e)
# 결과
# division by zero
위의 코드를 살펴보면, ZeroDivisionError이라는 에러를 e라는 변수에 담아 그 안의 메세지를 출력한 것을 볼 수 있습니다.
에러 별로 except를 작성하여 다양한 에러에 대한 다른 예외 처리를 진행할 수 있습니다.
try:
...
except ZeroDivisionError as err1:
print(err1)
except TypeError as err2:
print(err2)
finally 안의 코드는 try 안 코드에서 에러가 발생하든, 하지 않든 무조건 실행됩니다. 즉, 예외 처리 여부에 관계없이 실행이 되는거죠.
try:
print(3 / 0)
except:
print("오류입니다.")
finally:
print("이 문장은 실행됩니다.")
# 결과
# 오류입니다.
# 이 문장은 실행됩니다.
파이썬에서는 에러를 처리하는 것뿐만 아닌, 에러를 의도적으로 발생시키는 경우도 있습니다. 예를 들어, 이메일에서 '@'가 포함이 되지 않으면 의도적으로 에러를 일으켜 다시 입력하겠끔 할 수 있죠. 이렇듯 에러를 발생시킬 때, raise
를 사용합니다.
raise는 뒤에 에러명을 적어 해당되는 에러를 일으킵니다.
n = int(input())
if n % 2 == 0:
raise Exception
print("코드 끝")
만약 n
이 짝수라면 Exception이라는 에러를 일으키고 아래의 print("코드 끝")
은 실행되지 않을 것입니다. 이처럼 raise를 통해서 특정 경우에 의도적으로 에러를 일으켜 코드 흐름을 멈출 수 있습니다.
파이썬에서는 에러 또한 객체로, 클래스를 통해 자신만의 오류를 만들 수 있습니다. 이때는 Exception
클래스를 상속받습니다.
class UserError(Exception):
pass
raise UserError
print(1) # 출력되지 않습니다.