1. Exception 발생 시 기본 동작
Python에서 무엇인가가 잘못된 경우, python interpreter는 exception을 발생시킴.
- Exception : 동작을 중단시키는 에러를 가르킴.
- Exception handling : Exception 처리라고도 불리며, 발생한 exception을 처리하여 프로그램이 비정상적 중단(crash)되지않도록 처리하는 것을 가르킴.
Python에서 exception이 발생할 경우, 프로그램은 더 이상 수행하지 않고 종료된다.
(해당 문제를 그냥 안고 가는 것보다 사용자에게 문제가 발생했다는 것을 알리고 종료하는 게 일반적으로 더 나은 대처임)
참고로 이와 같은 종료를 crash 발생이라고도 한다.
Exception은 발생한 위치에서 함수호출스택을 따라 상위 호출자들에게 전달되어짐.
최종적으로는 PVM이 Exception 발생을 알리는 출력을 수행하고 종료함(crach)
이를 Exception Propagation 이라고 부름.
Python에서는 Exception 이라는 type으로 예외를 추상화하고 있음.
추상화(abstraction)에 대한 개념이 약하다면 다음 접은 글을 참조
다음의 hierarchy (계층)를 참고.
>>> ValueError.mro()
[<class 'ValueError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>]
Python의 Exception Hierarchy 와 간략한 설명은 다음 접은 글의 URL을 참고할 것.
2. try and except 를 통한 Exception 처리.
crash 없이 안정적으로 동작하는 프로그램을 만들려면,
발생가능한 exception들을 예측하고
발생가능한 부분에 이들 exception을 처리(handle)하는 code들을 작성해야만 한다.
이 같은 처리는 try와 except를 이용한다.
try:
exception이 발생가능한 부분
.
.
.
except 처리할_Exception0 as 별칭:
별칭을 통한 Exception 객체에 대한 접근
exception 발생시 실행되는 code 들.
.
.
.
except 처리할_Exception1 as 별칭:
또 다른 Type의 Exception에 대한 처리 부분.
앞서 except에서 처리가 되지 않은 경우에 처리가 됨(elif와 비슷)
.
.
.
finally:
exception 발생에 상관없이 수행되는 처리 부분.
.
.
.
위의 pseudo code는 Exception
을 처리하는 방법을 간략하게 나타내고 있음 (별칭=alias).
즉, 간단하게 except
code block들은 처리할 Exception 별로 만들어주면 된다.
- 참고로
finally
블럭은 생략가능함 - 꼭 마지막에 처리해야 하는 코드들이 있는 경우 사용. except
블록에서 처리하지 않는 Exception들은 Python interpreter에게 전달되고 프로그램 종료로 이어짐.raise
를 이용하여 except에서 처리하고 해당 exception을 다시 interpreter에게 넘길 수도 있음. (이 경우 프로그램은 exception으로 종료됨)raise ValueError('invalid argument')
와 같이 특정한 exception을 발생시키도록 처리할 수도 있음.
2-1. Example 1
다음 예는
0으로 나누어주는 ZeroDivisionError
와
잘못된 입력으로 인한 ValueError
를
handling하도록 만든 예제임.
def divide( a, b ):
return a/b
def main():
try:
a_str = input('numerator=?')
a = int(a_str)
b_str = input('denominator=?')
b = int(b_str)
r = divide(a,b)
print(f'result = {r}')
except ValueError as ve:
print(ve) # ve라는 alias를 통해 발생한 Exception 객체에 접근 가능.
print(f'Check your inputs')
raise ValueError("잘못된 input value입니다.")
except ZeroDivisionError as ze:
print(ze) # ze라는 alias를 통해 발생한 Exception 객체에 접근 가능.
print(f'denominator can not be zero!')
finally:
print('This python scirpt is finished.')
main()
- int로 casting이 안되는 입력을 할 경우, ValueError가 발생하고,
해당 Exception은 raise를 통해 interpreter에게 던져지므로 프로그램이 비정상종료됨. - 0이 입력된 경우, raise가 없이 exception에서 처리되어 프로그램은 정상종료됨.
- 비정상종료도 finally 블럭이 수행되고 나서임.
3. 모든 Exception 한 번에 처리
만일 모든 Exception을 한방에 처리하려면 except:
형태로 시작하는 exception처리 블록을 만들면 된다.
except:
모든 예외 처리.
- 모든 exception을 단 하나의 블럭으로 처리하는 이 같은 처리는 권하진 않는다. ==;;
- 해당
except
블럭은finally
와 다른 명시적으로 처리할 Exception을 지정한except
블럭 사이에 놓임. - 해당
except
블럭 위에 명시적으로 처리할 exception들에 대한 except블록을 놓여 있을 경우, 해당 exception을 제외한 exception들을 처리함.
참고로 모든 처리할 수 있는 예외들은
Exception의 subclass이므로except Excetion:
또는except Excetion as all_e:
등으로 모든 예외를 처리할 수 있음.
3-1. Example 2
한번에 모든 예외를 처리하는 exception 의 사용 예임.
def divide( a, b ):
return a/b
def main():
try:
a_str = input('numerator=?')
a = int(a_str)
b_str = input('denominator=?')
b = int(b_str)
r = divide(a,b)
print(f'result = {r}')
except ValueError as ve:
print(ve) # ve라는 alias를 통해 발생한 Exception 객체에 접근 가능.
print(f'Check your inputs')
except: # except Exception as all_e:
print(f'Exception Occured!')
raise
finally:
print('This python scirpt is finished.')
main()
- except 블럭에서 raise 가 있기 때문에 interpreter에게 발생한 exception이 전달됨.
- 즉, 이 경우 비정상 종료됨. 정상종료시키려면 except 블럭에서 raise 문을 제거해야 함.
- 비정상종료도 finally 블럭이 수행되고 나서 이루어짐.
비정상 종료시 PVM이 OS에게 반환하는 종료상태코드 를 확인해볼 것.
4. else 블럭.
except 블럭과 finally 블럭 사이에 위치하며,
try 블럭에서 exception이 발생하지 않은 경우에만 수행되는 블럭임.
def divide( a, b ):
return a/b
def main():
try:
a_str = input('numerator=?')
a = int(a_str)
b_str = input('denominator=?')
b = int(b_str)
r = divide(a,b)
print(f'result = {r}')
except ValueError as ve:
print(ve) # ve라는 alias를 통해 발생한 Exception 객체에 접근 가능.
print(f'Check your inputs')
except:
print(f'Exception Occurred!')
else:
print('There is no error!')
finally:
print('This python script is finished.')
main()
- exception이 발생하지 않은 경우
else
블럭과finally
블럭이 수행됨. finally
는 항상 수행됨.
참고자료
https://gist.github.com/dsaint31x/94e6ec9a825ce31cb215932cbc56a3fa#file-py_exception_handling-ipynb
py_exception_handling.ipynb
py_exception_handling.ipynb. GitHub Gist: instantly share code, notes, and snippets.
gist.github.com
https://ds31x.tistory.com/page/Python-Python-%EC%A0%95%EB%A6%AC
[Python] Python 정리
Programming Language and Python 소개2023.10.23 - [Python] - [Python] Programming Language and Introduction of Python. [Python] Programming Language and Introduction of Python.Computer and Program https://dsaint31.tistory.com/436 [CE] Computer and Progra
ds31x.tistory.com
[Python] Debugging : Traceback, Stacktrace, Backtrace ...
동의어 Python에서는 tracback (역추적) 이라는 용어가 많이 사용되지만, stack trace 또는 back trace라고도 불린다. 의미 Python의 실행 등에서 에러가 발생할 경우 출력되는 traceback 은 해당 에러가 발생한
ds31x.tistory.com
'Programming' 카테고리의 다른 글
[Python] Module Search Path and sys.path (0) | 2023.06.18 |
---|---|
[Python] importlib.reload : module 재적재 (0) | 2023.06.18 |
[Python] Strong Typing이란? with Object (1) | 2023.06.13 |
[Python] Variable (and Object) (0) | 2023.06.13 |
[Python] Arithmetic in Python and Augmented Assignment (0) | 2023.06.12 |