[코딩도장] day26. 파이썬 예외 처리 사용하기 - try except, else, finally
■ 들어가기
- 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그
▶ Unit38. 예외 처리 사용하기
- 38.1 try except로 사용하기
- 38.2 else와 finally 사용하기
- 38.3 예외 발생시키기
- 38.4 예외 만들기
0. 들어가기
- 예외 발생 시 스크립트 중단 없이 계속 실행하게 해주는 예외 처리 방법 학습
- ZeroDivisionError, AttributeError, NameError, TypeError 등등..
>> 38.1 try except로 사용하기 <<
- 사용법
try :
실행할 코드
except :
예외가 발생했을 때 처리하는 코드
목적 : 숫자를 0으로 나누었을 때 발생하는 예외(ZeroDivisionError) 처리 | |
소스 (try_except.py) | 결과 |
try : x = int(input('나눌 숫자를 입력하세요: ')) y = 10 / x print(y) except : # 예외 발생 시 실행 print('예외가 발생했습니다.') |
나눌 숫자를 입력하세요: 0 예외가 발생했습니다. |
- 예외 발생 시, 해당 라인의 코드 실행을 중단하고 바로 except로 가서 코드를 실행
1. 특정 예외만 처리하기
- except에 예외 이름을 지정해서 특정 예외 발생 시에만 처리 코드 실행
- 사용법
try :
실행할 코드
except 예외이름 :
예외가 발생했을 때 처리하는 코드
목적 : 예외이름을 지정해서 특정 에러 발생 시 처리 | |
소스 (try_except_exception.py) | 결과 |
y = [10, 20, 30] try : index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split()) print(y[index] / x) except ZeroDivisionError : print('숫자를 0으로 나눌 수 없습니다.') except IndexError : print('잘못된 인덱스입니다.') |
인덱스와 나눌 숫자를 입력하세요: 2 0 숫자를 0으로 나눌 수 없습니다. 인덱스와 나눌 숫자를 입력하세요: 3 5 잘못된 인덱스입니다. |
2. 예외의 에러 메시지 받아오기
- except에서 as 뒤에 변수를 지정하면 발생한 예외의 에러 메시지 가져올 수 있음
- 보통 변수는 예외(exception)의 e를 따서 사용
- 사용법
try :
실행할 코드
except 예외 as 변수 :
예외가 발생했을 때 처리하는 코드
목적 : 변수 지정해서 에러 메시지 취득 | |
소스 (try_except_as.py) | 결과 |
y = [10, 20, 30] try : index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split()) print(y[index] / x) except ZeroDivisionError as e : print('숫자를 0으로 나눌 수 없습니다.', e) except IndexError as e : print('잘못된 인덱스입니다.', e) |
인덱스와 나눌 숫자를 입력하세요: 2 0 숫자를 0으로 나눌 수 없습니다. division by zero 인덱스와 나눌 숫자를 입력하세요: 3 5 잘못된 인덱스입니다. list index out of range |
- 모든 예외의 에러 메시지를 출력하고 싶은 경우 except에 Exception을 지정하고 as 뒤에 변수 입력
( Exception은 에러 메시지의 조상, 모든 예외는 Exception을 상속받아 구현됨 )
except Exception as e : print('예외가 발생했습니다 - ', e) |
>> 38.2 else와 finally 사용하기 <<
- 예외가 발생하지 않은 경우 코드를 실행하는 else 구현
- else는 except 바로 다음에 와야 함
- try ~ except ~ else 와 같이 사용해야 하며, except 생략 불가
- 사용법
try :
실행할 코드
except :
예외가 발생했을 때 처리하는 코드
else :
예외가 발생하지 않았을 때 실행할 코드
목적 : 예외가 발생하지 않은 경우 처리 | |
소스 (try_exception_else.py) | 결과 |
try : x = int(input('나눌 숫자를 입력하세요: ')) y = 10 / x except ZeroDivisionError : print('숫자를 0으로 나눌 수 없습니다.') else : print(y) |
나눌 숫자를 입력하세요: 2 5.0 나눌 숫자를 입력하세요: 0 숫자를 0으로 나눌 수 없습니다. |
1. 예외와는 상관없이 항상 코드 실행하기
- finally를 사용해서 예외 발생 여부와 상관없이 항상 코드를 실행
- try ~ except ~ else ~ finally 와 같이 사용해야 하며, except와 else 생략 가능
- 사용법
try :
실행할 코드
except :
예외가 발생했을 때 처리하는 코드
else :
예외가 발생하지 않았을 때 실행할 코드
finally :
예외 발생 여부와 상관없이 항상 실행할 코드
목적 : try의 코드 끝나면 항상 finally 수행 | |
소스 (try_except_else_finally.py) | 결과 |
try : x = int(input('나눌 숫자를 입력하세요: ')) y = 10 / x except ZeroDivisionError : print('숫자를 0으로 나눌 수 없습니다.') else : print(y) finally : print('코드 실행이 끝났습니다.') |
나눌 숫자를 입력하세요: 2 5.0 코드 실행이 끝났습니다. 나눌 숫자를 입력하세요: 0 숫자를 0으로 나눌 수 없습니다. 코드 실행이 끝났습니다. |
[참고] try 는 함수가 아니므로 '스택 프레임'을 생성하지 않으며 따라서 try 안에서 생성된 변수를 try 바깥에서 사용가능함!
>> 38.3 예외 발생시키기 <<
- 파이썬에서 정해진 예외가 아닌 개발자가 직접 예외 발생 가능
- 사용법 : raise 예외('에러메시지')
목적 : 임의의 예외 발생 | |
소스 (try_except_raise.py) | 결과 |
try : x = int(input('3의 배수를 입력하세요: ')) if x % 3 != 0 : raise Exception('3의 배수가 아닙니다.') print(x) except Exception as e : print('예외가 발생했습니다.', e) |
3의 배수를 입력하세요: 5 예외가 발생했습니다. 3의 배수가 아닙니다. |
- raise로 예외 발생 시 raise 이후 코드는 실행되지 않고 바로 except로 넘어감
1. raise의 처리 과정
목적 : raise 처리 과정 확인 (try ~ except 없는 상태) | |
소스 (try_except_function_raise.py) | 결과 |
def three_multiple() : x = int(input('3의 배수를 입력하세요: ')) if x % 3 != 0 : raise Exception('3의 배수가 아닙니다.') print(x) try : three_multiple() except Exception as e : print('예외가 발생했습니다.', e) |
3의 배수를 입력하세요: 5 예외가 발생했습니다. 3의 배수가 아닙니다. |
- three_multiple 함수 안에 try ~ except 가 없는 상태에서 에러 발생하여 함수 바깥의 except에서 예외 처리됨
- 즉, 예외 발생하더라도 현재 코드 블록에서 처리할 except가 없다면 except가 나올 때까지 상위 코드 블록으로 이동
- 최종적으로 처리할 except가 없는 경우 코드 실행 중지 후 에러 발생
2. 현재 예외를 다시 발생시키기
목적 : except로 발생한 예외를 raise로 다시 상위 코드 블록에서 다시 예외 처리 | |
소스 (try_except_raise_in_except.py) | 결과 |
def three_multiple() : try : x = int(input('3의 배수를 입력하세요: ')) if x % 3 != 0 : raise Exception('3의 배수가 아닙니다.') print(x) except Exception as e : print('three_multiple 함수에서 예외가 발생했습니다.', e) raise try : three_multiple() except Exception as e : print('스크립트 파일에서 예외가 발생했습니다.', e) |
3의 배수를 입력하세요: 5 three_multiple 함수에서 예외가 발생했습니다. 3의 배수가 아닙니다. 스크립트 파일에서 예외가 발생했습니다. 3의 배수가 아닙니다. |
√ 대체 이런 코드는 왜 사용하는 걸까??
>> 38.4 예외 만들기 <<
- 예외 : 내장된 예외, 사용자 정의 예외
- 사용자 정의 예외 : 프로그래머가 직접 만든 예외
- Exception을 상속받아 새로운 클래스를 만듦
- 사용법
class 예외이름(Exception) :
def __init__(self) :
super().__init__('에러메시지')
목적 : 사용자 정의 예외 사용 | |
소스 (exception_class.py) | 결과 |
class NotThreeMultipleError(Exception) : def __init__(self) : super().__init__('3의 배수가 아닙니다.') def three_multiple() : try : x = int(input('3의 배수를 입력하세요: ')) if x % 3 != 0 : raise NotThreeMultipleError print(x) except Exception as e : print('예외가 발생했습니다.', e) three_multiple() |
3의 배수를 입력하세요: 5 예외가 발생했습니다. 3의 배수가 아닙니다. |