[python] 예외 처리 사용하기

try except로 사용하기

# 1 / x 와 같이 x의 값에 따라 에러가 나기도 하고 정상적으로 동작하기도 하는 코드가 있는데,
# 이 경우에는 x가 0이면 에러가 난다. 이런 상황을 예외라고 하는데,
# 이런 예외를 처리해주는 방법을 알아보자.

# 먼저, try except를 사용해 예외를 처리해보자.
# try:
#     실행할 코드
# except:
#     예외가 발생했을 때 처리하는 코드
try:
    x = int(input('나눌 숫자를 입력하세요: '))
    y = 10 / x
    print(y)
except:
    print('예외 발생')

# 0을 입력하면 예외 발생이 출력되는 것을 정상적으로 확인할 수 있다.
# 이처럼 try에서 예외가 발생하면 더 진행하지 않고 바로 except로 이동해서 예외 처리 코드를 실행해준다.

# except에 예외 이름을 지정해서 특정 예외가 발생했을 때만 처리하는 코드를 만들어보자.
# try:
#     실행할 코드
# except 예외 이름:
#     예외가 발생했을 때 처리하는 코드
lst = [1, 2, 3]
try:
    index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split())
    print(lst[index] / x)
except ZeroDivisionError:  # 나눌 수로 0을 입력했을 때
    print('숫자는 0으로 나눌 수 없습니다.')
except IndexError:  # 인덱스로 3 이상을 입력했을 때
    print('잘못된 인덱스입니다.')

# except에서 as 뒤에 변수를 지정하면 발생한 예외의 에러 메시지를 받아올 수 있다.
try:
    index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split())
    print(lst[index] / x)
except ZeroDivisionError as e:  # 나눌 수로 0을 입력했을 때
    print('숫자는 0으로 나눌 수 없습니다.', e)  # 숫자는 0으로 나눌 수 없습니다. division by zero
except IndexError as e:  # 인덱스로 3 이상을 입력했을 때
    print('잘못된 인덱스입니다.', e)  # 잘못된 인덱스입니다. list index out of range

# 예외도 클래스 상속으로 구현되며 파이썬에서 새로운 예외를 만들 때는 보통 Exception을 상속받아 구현한다.
# 계층도는 아래 코드에서 확인할 수 있다.
# Built-in Exceptions: https://docs.python.org/3/library/exceptions.html#exception-hierarchy

else와 finally 사용하기

# 이번에는 예외가 실행하지 않았을 때 코드를 실행하는 else와,
# 예외 발생 여부와 관계없이 항상 코드를 실행하는 finally를 사용해보자.
# else는 except 바로 뒤에 와야하고, except를 생략할 수 없다.
# finally는 except와 else를 생략할 수 있다.
# try:
#     실행할 코드
# except:
#     예외가 발생했을 때 처리하는 코드
# else:
#     예외가 발생하지 않았을 때 실행할 코드
# finally:
#     항상 실행할 코드
try:
    x = int(input('나눌 숫자를 입력하세요: '))
    y = 10 / x
except ZeroDivisionError as e:
    print('숫자는 0으로 나눌 수 없습니다.', e)  # 숫자는 0으로 나눌 수 없습니다. division by zero
else:
    print('결과는', y)
finally:
    print('코드 실행 종료')

예외 발생시키기

# raise에 예외를 지정하고 에러 메시지(생략 가능)를 넣으면 에러를 발생시킬 수 있다.
# raise 예외('에러메시지')
# 예외에는 Exception 뿐만 아니라 ZeroDivisionError, IndexError 등 다른 것을 사용해도 상관없다.
try:
    x = int(input('나눌 수를 입력하세요1: '))
    if x == 0:
        raise Exception('숫자는 0으로 나눌 수 없습니다.')
except Exception as e:
    print(e)  # 숫자는 0으로 나눌 수 없습니다.
else:
    print(10 / x)
finally:
    print('코드 실행 종료')


# 이번에는 raise의 처리 과정을 알아보자.
# 함수 안에서 raise를 사용하지만 함수 안에는 try except 문이 없는 상황이다.
def division():
    x = int(input('나눌 수를 입력하세요2: '))
    if x == 0:
        raise ZeroDivisionError('숫자는 0으로 나눌 수 없습니다.')
    print(10 / x)


# 함수 안에서 try except문이 없는 상태로 raise가 발생하면 함수 바깥의 except에서 예외가 처리된다.
try:
    division()
except Exception as e:
    print(e)


# 이번에는 try except 에서 처리한 예외를 다시 발생시키는 방법이다.
# except 안에서 raise를 사용하면 현재 예외를 다시 발생시킨다.
def division2():
    try:
        x = int(input('나눌 수를 입력하세요3: '))
        if x == 0:
            raise ZeroDivisionError('숫자는 0으로 나눌 수 없습니다.')
        print(10 / x)
    except Exception as e:
        print('division2 함수 내에서 예외가 발생했습니다.', e)  # division2 함수 내에서 예외가 발생했습니다. 숫자는 0으로 나눌 수 없습니다.
        raise  # raise로 현재 예외를 다시 발생시켜서 상위 코드 블록으로 넘긴다.


try:
    division2()
except Exception as e:
    print('스크립트 파일에서 예외가 발생했습니다.', e)  # 스크립트 파일에서 예외가 발생했습니다. 숫자는 0으로 나눌 수 없습니다.

# raise만 사용하면 같은 예외를 상위 코드 블록으로 넘기지만 따로 다른 예외를 지정해줄 수도 있다.

예외 만들기

# 예외를 만드는 방법은 간단하다.
# Exception 클래스를 상속받아 새로운 클래스를 만들면 된다.
# 그리고 __init__ 메소드에서 super().__init__을 호출하며 에러 메시지를 넣어주면 된다.
# class 예외이름(Exception):
#     def __init__(self):
#         super().__init__('에러메시지')
class MyZeroDivisionError(Exception):
    def __init__(self):
        super().__init__('숫자는 0으로 나눌 수 없습니다.')


try:
    x = int(input('나눌 숫자를 입력하세요: '))
    if x == 0:  # 예외를 발생시킬 때에는 raise로 새로 만든 예외를 지정해주면 된다.
        raise MyZeroDivisionError
    print(10 / x)
except Exception as e:
    print(e)  # 숫자는 0으로 나눌 수 없습니다.


# 다음과 같이 Exception만 상속받고 아무것도 구현하지 않아도 된다.
class NotThreeMultipleError(Exception):
    pass


try:
    x = int(input('3의 배수를 입력하세요: '))
    if x % 3 != 0:
        raise NotThreeMultipleError('3의 배수가 아닙니다.')  # 이 때는 예외를 발생시킬 때 에러 메시지를 넣어주면 된다.from
    print(x)
except Exception as e:
    print(e)  # 3의 배수가 아닙니다.

파일 예외 처리하기

# 파일이 있으면 파일의 내용을 출력하고, 파일이 없으면 에러 메시지를 출력하는 코드를 만들어보자.
try:
    file = open('text.txt', 'r')
except FileNotFoundError as e:
    print('파일이 없습니다.', e)  # 파일이 없습니다. [Errno 2] No such file or directory: 'text.txt'
else:
    s = file.read()
    file.close()

Updated:

Leave a comment