Python_07(예외처리)
오류 : 함수나 메소드가 처리 도중 다음 명령문을 실행할 수 없는 상황
오류 중 처리가능한 것을 Exception(예외) 라고 한다. 그리고 그 예외를 처리하는 것을 Exception Handling 이라고 한다.
오류의 종류
1. 파이썬 문법을 어겨서 발생하는 오류
- 코드 상 100% 발생하는 오류
- 코드를 수정해야 한다.
- 보통 이런 오류는 컴파일 방식 언어의 경우 컴파일 때 에러를 내서 수정하도록 한다.(Python은 해당되지 않는다.)
2. 실행 환경의 문제로 발생하는 오류
- 코드상에서는 Exception의 발생여부를 확신할 수 없다.
- 만약 발생할 경우 어떻게 처리할지를 구현해야 한다.
1. 예외처리 -> 2. 예외 발생 -> 3. 사용자 정의 예외 class 생성
예외처리(Exception handling) : try, except 구문 (try, except, finally, else가 있지만 else는 잘 쓰지 않는다.)
# try, except 구문
try:
Exception 발생가능한 코드 블록 # try block
except [Exception클래스 이름 [as 변수]] :
처리 코드 # except block
try block : Exception 발생 가능한 코드와 그 코드와 연결된 코드들을 블록으로 묶는다.
- 연결된 코드 : Exception이 발생 하지 않았을 때 실행되는 코드
except block : 발생한 Exception을 처리하는 코드 블록 작성
- try block 먼저 실행하다가 exception 발생시에만 except block 실행
- 모든 exception을 처리하는 경우 except: 선언
- 특정 exception을 처리하는 경우 except Exception클래스 이름: 선언
모든 Exception들은 클래스로 정의 되어 있다. 그 클래스 이름을 적어준다.
Exception들을 각각 처리할 수 있으며 이 경우 except 구문(처리구문)을 연속해서 작성하면 된다.
print('프로그램 시작') # 1
try:
num = int(input('정수:')) # 2 Exception 발생 가능성이 있는 코드. (ex. 문자열 입력 -> ValueError)
result = 10 // num # 3 Exception 발생 가능성이 있는 코드. (ex. 0 입력 -> ZeroDivisionError)
print('결과:',result) # 4
except:
print('실행도중 문제가 발생했습니다. 일단 처리했습니다.') # EH(Exception Handling)
print('프로그램 종료') # 5
# 정상흐름 : 1, 2, 3, 4, 5
# 2번에 Exception 발생 : 1, 2(Exception 발생 -> x), 3(x), 4(x), EH, 5
# -> 1, EH, 5
# 3번에 Exception 발생 : 1, 2, 3(Exception 발생 -> x), 4(x), EH, 5
# -> 1, 2, EH, 5
# Exception이 발생할 수 있는 구간이 여러개다 -> Exception 종류별로 따로 처리해야함.
# Exception 종류별로 따로 처리.
print('프로그램 시작') # 1
try:
num = int(input('정수:')) # 2 Exception 발생 가능성이 있는 코드. ex) 문자열 입력
result = 10 // num # 3 Exception 발생 가능성이 있는 코드. ex) 0 입력
print('결과:',result) # 4
# print('결과2',result2) NameError 발생코드
print(1 + "1") # TypeError 발생코드
except ValueError as ve: # ValueError를 처리하는 block
print('정수로 변환하지 못했습니다. ValueError 발생') # EH1
print('ve 변수출력 : ', ve)
except ZeroDivisionError as ze: # ZeroDivisionError 를 처리하는 block
print('0으로는 못나눕니다. ZeroDivisionError') # EH2
print('ze 변수출력 : ', ze)
except Exception as e: # 위의 두 Exception을 제외한 나머지 Exception을 처리.
print('실행도중 문제가 발생했습니다. 일단 처리했습니다.') # EH3
print('e 변수출력 : ', e)
print('프로그램 종료') # 5
# try에서 ValueError 발생 (2) : 1, EH1, 5
# try에서 ZeroDivisionError 발생(3) : 1, 2, EH2, 5
# try에서 ValueError, ZeroDivisionError를 제외한 exception발생(NameError) : 1, 2, 3, 4, EH3, 5
finally 구문 : 예외 발생여부, 처리 여부와 관계없이 무조건 실행되는 코드블록(무조건 실행)
- try 구문에 반드시 실행되야 하는 코드블록을 작성할때 사용한다. (입출력 관련해서 사용)
구문순서
1. try - except - finally
2. try - except
3. try - finally
print('시작')
try:
print(1)
a = 10 / 2
print(2)
b = int('ab') # -> ValueError 발생
except ValueError:
print(3)
finally:
print('무조건실행할코드') # 오류가 발생해도 무조건 실행
print('종료')
try:
a = int(input())
except:
print('예외발생')
else:
print(a + 10) # except: 과 finally: 사이에 else: -> except이 나지 않는다면 else block 코드 실행
# 보통 else:는 쓰지 않고 else block에 넣을 코드들을 try block에 모두 넣는다.
finally:
print('무조건 실행할 코드')
Exception 발생 시키기(사용자 정의 Exception 클래스 구현)
- Exception 클래스를 상속받는다.
- 클래스 이름은 Exception 상황을 설명할 수 있는 이름을 준다.
# 월에 1 ~ 12 이외의 값을 대입할 때 발생시킬 Exception 클래스 정의
class InvaildMonthException(Exception):
def __init__(self, invalid_month):
# attribute로 입력된 "잘못된 월" 값을 저장.
self.invalid_month = invalid_month
def __str__(self):
# Exception 메세지를 문자열로 반환.
return f"{self.invalid_month}는 사용할 수 없는 월입니다. 1 ~ 12월 만 가능합니다."
raise : Exception을 강제로 발생시킨다.
구문 : raise Exception객체
def use_month(month):
if month < 1 or month > 12:
# 처리할 수 없는 월. 호출한 곳으로 돌아간다. -> 비정상(예외발생)종료상태로 돌아간다.
raise InvaildMonthException(month) # 비정상 return
else:
print('month : ', month) # 사용
# day와 year는 있다고 가정
use_month(5) # 1. 월사용
print('use_day(30)') # 2. 일 사용
print('use_year(2020)') # 3. 년도를 사용
print('시작') # 1
try:
use_month(50) # 2. Exception 발생 가능성이 있는 코드 : 처리할 수 없는 월 입력, 에러 발생 -> 에러코드 : InvaildMonthException 출력
print('use_day(30)') # 2. 일 사용
print('use_year(2020)') # 3. 년도를 사용
except InvaildMonthException as e: # e에는 raise한 Exception 객체가 할당.
print('예외 처리함', e) # e -> InvaildMonthException 클래스의 return 값
print(e.invalid_month)
print('종료') # 5