오류 발생이 예상되는부분에, 오류로 인한 의도하지 않은 강제 종료 대신 실행될 로직을 추가하여 대처 가능하다.
문제 : 오류 발생 > 실행 정지
해결 : 오류 발생 > 오류 대처 > 정상 작동
10.2 예외란? error
정수를 0으로 나누기
- ZeroDivisionError
# 정수를 0으로 나누기
print("4/0 = ", 4/0)
# ---------------------------------------------------------------------------
# ZeroDivisionError Traceback (most recent call last)
# <ipython-input-2-b0386c54c776> in <module>
# 1 # 0으로 나누기
# 2
# ----> 3 print("4/0 = ", 4/0)
# ZeroDivisionError: division by zero
인덱스 범위를 벗어난 접근
- IndexError
# 인덱스를 범위를 벗어난 접근
lst = [1,2,3,4]
print(lst[999])
# IndexError Traceback (most recent call last)
# <ipython-input-3-94cd13c3b4a0> in <module>
# 2
# 3 lst = [1,2,3,4]
# ----> 4 print(lst[999])
# IndexError: list index out of range
try:
x = int(input('나눌 숫자를 입력하세요: '))
y = 10 / x
except: # 숫자를 0으로 나눠서 에러가 발생했을 때 실행됨
print('숫자를 0으로 나눌 수 없습니다.')
else: # try의 코드에서 예외가 발생하지 않았을 때 실행됨
print(y)
finally: # 예외 발생 여부와 상관없이 항상 실행됨
print('코드 실행이 끝났습니다.')
if 조건문으로 예외 처리
# if 조건문 예외 처리의 한계
while True:
div = int(input('10을 나눌 정수를 입력하세요: '))
if div == 999:
print('프로그램을 종료합니다.')
break
elif div != 0:
res = 10 / div # 예외 예상 지점
print(int(res))
else:
print('예외가 발생했습니다.')
try: ~ except
try: 블럭의 오류 종류 상관없이, 모든 예외에 대해 except: 구문 실행
# 예상 오류
# 0 입력시, ZeroDivisionError
# 문자 입력시, ValueError
while True:
try:
div = int(input('10을 나눌 정수를 입력하세요: '))
res = 10 / x # 예외 예상 지점
print(res)
except: # 예외 발생시 실행됨
print('예외가 발생했습니다.')
try: ~ except 오류유형:
try: 블럭의 오류가, 특정 오류 유형일때 except: 구문 실행
# 0 입력시, ZeroDivisionError 은 예외 처리 대상이지만
# 문자 입력시, ValueError 에 대해서는 처리하지 못한다.
while True:
try:
div = int(input('10을 나눌 정수를 입력하세요: '))
res = 10 / x # 예외 예상 지점
print(res)
except ZeroDivisionError:
print('예외가 발생했습니다.\n0으로 나눌 수 없습니다.')
try: ~ except 오류유형: ~ except 오류유형:
# 오류의 종류에 따라 각각 다른 실행 코드를 except 블럭에 작성할 수 있다.
while True:
try:
div = int(input('10을 나눌 정수를 입력하세요: '))
res = 10 / x # 예외 예상 지점
print(res)
except ZeroDivisionError:
print('예외가 발생했습니다.\n0으로 나눌 수 없습니다.')
except ValueError:
print('예외가 발생했습니다.\n입력값이 숫자가 아닙니다.')
10.4 예외 처리 예시
오류 무시
# 오류 발생되어도 강제적으로 다음 로직이 실행되도록 한다.
try:
file = open("info.txt", "r")
except FileNotFoundError as e:
pass
print(e)
오류 발생에 상관없이 실행하는 finally:
# case1. 정수 입력시 정상 작동
# case2. 0 입력시, ZeroDivisionError
# case3. 문자 입력시, ValueError
while True:
try:
div = int(input('10을 나눌 정수를 입력하세요: '))
res = 10 / div # 예외 예상 지점
print(f"10/{div} = ", res)
except: # 예외 발생시 실행됨
print('예외가 발생했습니다.')
finally:
print('finally는 무조건 실행됩니다.\n')
# 문제
# finally 구문의 유무 비교
while True:
try:
div = int(input('10을 나눌 정수를 입력하세요: '))
res = 10 / div # 예외 예상 지점
print(f"10/{div} = ", res)
except: # 예외 발생시 실행됨
print('예외가 발생했습니다.')
print('finally는 무조건 실행됩니다.\n')
while True:
try:
print("try 구문 실행")
break
print("break 뒤 구문")
except:
print("except 실행")
finally:
print("finally 실행")
print("while 마지막 줄")
print("종료")
10.5 강제 예외 발생 처리
raise 사용 방법
try:
x = int(input('3의 배수를 입력하세요: '))
if x % 3 != 0:
raise Exception('3의 배수가 아닙니다.') # 예외를 발생
print(x)
except Exception as e:
print('예외가 발생했습니다.', e)
함수에서 raise 적용 방법
def three_multiple():
try:
x = int(input('3의 배수 입하세요: '))
if x % 3 != 0:
raise Exception(f'입력하신 {x}는 3의 배수가 아닙니다.') # 예외 발생
print(x)
except Exception as e:
print('three_multiple 함수에 예외가 발생했습니다.', e)
raise # raise 예외 재실행 후 상위 코드 블록으로 전달
try:
three_multiple()
except Exception as e: # 하위 코드 블록에서도 예외 처리 실행
print('스크립트 파일에 예외가 발생했습니다.', e)
10.6 예외 클래스 정의
class NotThreeMultipleError(Exception): # Exception 상속
def __init__(self):
super().__init__('[예외] 3의 배수가 엽력되지 않았습니다.') # 오버라이딩
def three_multiple():
try:
x = int(input('3의 배수를 입력하세요: '))
if x % 3 != 0:
raise NotThreeMultipleError # 예외 발생
print("3의 배수:", x)
except Exception as e:
print('e 실행:', e)
three_multiple()