본문 바로가기
Programming/Python

예외 처리 사용하기

by 용스토리랜드 2023. 3. 15.

아래의 포스팅을 읽고 나면 현재 스크립트가 이해될 것이다. 

y = [10, 20, 30]
 
try:
    index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split())
    print(y[index] / x)
except ZeroDivisionError as eo:                    # as 뒤에 변수를 지정하면 에러를 받아옴
    print('숫자를 0으로 나눌 수 없습니다.', eo)    # e에 저장된 에러 메시지 출력
except IndexError as eo:
    print('잘못된 코드 : print(y[index] / x)', eo)

import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

print("hello world")

# input : 3, 5
# output
>>> 잘못된 코드 : print(y[index] / x) list index out of range
>>> hello world

 

예외(exception)코드를 실행하는 중에 발생한 에러를 뜻합니다.

다음과 같이 10을 어떤 값으로 나누는 함수 ten_vid 가 있을 때 인수에 따라 정상으로 동작하기도 하고 에러가 나기도 한다.

def ten_div(x) :
  return 10 / x
ten_div(2)

이 함수에 2를 넣으면 5. 이 나옵니다.

 

하지만 0을 넣으면 실행하는 중에 에러가 발생합니다. 이런 상황을 예외라고 하는데 여기서는 어떤 숫자를 0으로 나누어서 ZeroDivisionError 예외가 발생했습니다. 

>>> ten_div(0)
Traceback (most recent call last):
  File "<pyshell#121>", line 1, in <module>
    ten_div(0)
  File "<pyshell#119>", line 2, in ten_div
    return 10 / x
ZeroDivisionError: division by zero

ZeroDivisionError 뿐만 아니라 AttributeError, NameError, TypeError 등 다양한 에러들도 모두 예외입니다. 

 

이번에는 예외가 발생했을 때도 스크립트 실행을 중단하지 않고(예외, 에러 가 난 코드 뒤를 계속해서 실행 시켜 줄 수 있음) 계속 실행하게 해주는 예외 처리 방법에 대해 알아보겠습니다. 

 

# try except 로 사용하기 

예외 처리를 하려면 다음과 같이 try 에 실행할 코드를 넣고 except 에 예외가 발생했을 때 처리하는 코드를 넣는다.

try : 
  실행할 코드 
except :
  예외가 발생했을 때 처리하는 코드
try :
  x = int(input('나눌 숫자를 입력하세요:')
  y = 10 / x
  print(y)
  
except : # 예외가 발생했으 때 실행됨
  print('예외가 발생했습니다.')
# output
나눌 숫자를 입력하세요 : 0 (입력)
예외가 발생했습니다.

 

 

 

숫자를 0으로 나누면 ZeroDivisionError 예외가 발생합니다. 여기서는 except 에서 예외 처리를 하도록 만들었으며 '예외가 발생했습니다.' 가 출력됩니다.

try 의 코드가 에러 없이 잘 실행 되면 except 의 코드는 실행되지 않고 그냥 넘어갑니다. 즉, try 의 코드에서 에러가 발생했을 때만 except 의 코드가 실행된다.

 

# 특정 예외만 처리하기

이번에는 except 에 예외 이름을 지정해서 특정 예외가 발생했을 때만 처리 코드를 실행하도록 만들어보겠습니다.

try :
  실행할 코드 
except 예외이름 : 
  예외가 발생했을 때 처리하는 코드

다음과 같이 정수 두 개를 입력받아서 하나는 리스트의 인덱스로 사용하고, 하나는 나누는 값으로 사용한다. 그리고 except 를 두 개 사용하고 각각 ZeroDivisionError 와 IndexError 를 지정한다.

y = [10, 20, 30]

try : 
  # 실행할 코드
  index, x = map(int, input("인덱스와 나눌 숫자를 입력하세요:").split())
  print(y[index] / x)
  
# except 예외이름
# 예외이름 : 파이썬에 실재하는 예외이름이어야 한다.
except ZeroDivisionError : # 숫자를 0으로 나눠서 에러가 발생했을 때 실행됨 
  # 예외(error) 가 발생했을 때 처리할 코드
  print("숫자를 0으로 나눌 수 없습니다.")
  
except IndexError : # 범위가 벗어난 인덱스에 접근하여 에러가 발생했을 때 실행됨
  print("잘못된 인덱스입니다."
  
>>> 인덱스와 나눌 숫자를 입력하세요: 2 0 (입력)
>>> 숫자를 0으로 나눌 수 없습니다.

>>> 인덱스와 나눌 숫자를 입력하세요: 3 5 (입력)
>>> 잘못된 인덱스입니다.

# 예외의 에러 메시지 받아오기 

특히 except 에서 as 뒤에 변수를 지정하면 발생한 예외 (파이썬에 구현되어 있는 예외) 의 에러 메시지를 받아올 수 있다.

 

try :
  실행할 코드 
except 예외 as 변수 : 
  예외가 발생했을 때 처리하는 코드
y = [10, 20, 30]
 
try:
    index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split())
    print(y[index] / x)

# 변수는 e 로 해도되고 다른 어떠한 변수명을 설정해도 괜찮다.
except ZeroDivisionError as e:                    # as 뒤에 변수를 지정하면 에러를 받아옴
    print('숫자를 0으로 나눌 수 없습니다.', e)    # e에 저장된 에러 메시지 출력
except IndexError as e:
    print('잘못된 인덱스입니다.', e)
>>> 인덱스와 나눌 숫자를 입력하세요: 2 0 (입력)
>>> 숫자를 0으로 나눌 수 없습니다. division by zero

>>> 인덱스와 나눌 숫자를 입력하세요: 3 5 (입력)
>>> 잘못된 인덱스입니다. list index out of range

2 0 , 3 5 처럼 예외가 발생하는 숫자를 넣어보면 해당 예외에 해당하는 에러 메시지가 출력됩니다. 단, 예외가 여러 개 발생하더라도 먼저 발생환 예외의 처리 코드만 실행된다.  (또는, 예외 중에서 높은(상위) 계층의 예외부터 처리됩니다. ex) 기반 클래스(superclass) > 파생 클래스(subclass))

 

# 예외의 이름을 모르는 경우에는 Exception as 를 통해 해결할 수 있습니다.

except Exception as e : # 예외의 이름을 모를 때
  print('error', e)

예외 처리는 에러가 발생하더라도 스크립트의 실행을 중단시키지 않고 계속 실행하고자 할 때 사용합니다. 


참고 | 예외 계층

예외도 클래스 상속으로 구현되며 다음과 같은 계층으로 이루어져 있습니다. 보통 파이썬에서 새로운 예외를 만들 때는 Exception을 상속받아서 구현합니다.

전체 계층도는 파이썬 공식 문서를 참조하세요.

Built-in Exceptions: https://docs.python.org/3/library/exceptions.html#exception-hierarchy

 

반응형