티스토리 뷰
[Python] Exception 클래스 그리고 예외처리(try, except, raise, finally)
알 수 없는 사용자 2021. 11. 7. 05:02
try:
print("나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요 : "))
num2 = int(input("두 번째 숫자를 입력하세요 : "))
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
print("에러! 잘못된 값을 입력하였습니다.")
except ZeroDivisionError as err:
print(err)
except Exception as err:
print("알 수 없는 에러가 발생하였습니다.")
print(err)
기본적으로 try: 어쩌구저쩌구 except: 어쩌구저쩌구 형태가 됩니다.
만약 특정 예외처리가 발생했을 때는 except ValueError: 와 같은 형태로 예외처리를 할 수 있습니다.
그리고 except Exception as err: print(err) 와 같은 형태로 예외처리가 발생했을 때 바로 프로그램이 꺼지지 않고 어떤 내용의 오류인지 출력하게도 할 수 있습니다.
Python 에 존재하는 Exception 들이 어떤 것이 있는 지 확인하기 위해서는 Exception Class 의 하위 Class 목록을 확인해보면 알 수 있습니다.
Python 코드를 실행해서 확인할 수도 있습니다만, 아래와 같이 확인하기가 영 별로입니다.
>>> Exception.__subclasses__()
[<class 'TypeError'>, <class 'StopAsyncIteration'>, <class 'StopIteration'>, <class 'ImportError'>, <class 'OSError'>, <class 'EOFError'>, <class 'RuntimeError'>, <class 'NameError'>, <class 'AttributeError'>, <class 'SyntaxError'>, <class 'LookupError'>, <class 'ValueError'>, <class 'AssertionError'>, <class 'ArithmeticError'>, <class 'SystemError'>, <class 'ReferenceError'>, <class 'MemoryError'>, <class 'BufferError'>, <class 'Warning'>, <class 'locale.Error'>, <class 'warnings._OptionError'>, <class 're.error'>, <class 'sre_parse.Verbose'>, <class 'socket._GiveupOnSendfile'>, <class 'tokenize.TokenError'>, <class 'tokenize.StopTokenizing'>, <class 'struct.error'>, <class '_pickle.PickleError'>, <class 'pickle._Stop'>, <class '_queue.Empty'>, <class 'queue.Full'>, <class 'copy.Error'>, <class '_ctypes.COMError'>, <class 'ctypes.ArgumentError'>, <class 'pyreadline.lineeditor.history.EscapeHistory'>, <class 'pyreadline.error.ReadlineError'>, <class 'pyreadline.modes.emacs.LeaveModeTryNext'>, <class 'zlib.error'>, <class '_lzma.LZMAError'>, <class 'shutil.RegistryError'>, <class 'shutil._GiveupOnFastCopy'>, <class 'subprocess.SubprocessError'>, <class 'pyreadline.rlmain.MockConsoleError'>]
그래서 일반적으로 문서를 살펴볼 수 있습니다. https://docs.python.org/3/library/exceptions.html
위 문서는 Python 3.10.0 문서인데, exceptions 관련 내용을 담고 있습니다.
그리고 위 문서에서 Exceptions Class 하위 클래스에 어떤 클래스들이 존재하는지만 확인해보았는데요. 아래와 같습니다.
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- EncodingWarning
+-- ResourceWarning
만약에 try, except 문 안에서 강제로 예외를 발생시키고 싶다면 raise 키워드를 사용해야합니다.
try:
print("한 자리 숫자 나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요 : "))
num2 = int(input("두 번째 숫자를 입력하세요 : "))
if num1 >= 10 or num2 >= 10:
raise ValueError
print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except ValueError:
print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
위에서 보면 num1 이 10보다 크거나 같고 num2도 10보다 크거나 같게 되면 강제로 ValueError 라는 예외처리가 발생하도록 하였습니다. 그렇게되면 실행흐름이 바로 except ValueError로 바로 이동하게 됩니다.
예외처리를 꼭 Built-in Exception 만 사용하지 않아도 됩니다. 우리가 직접 정의하는 이른바 사용자 정의 예외처리도 할 수 있습니다. 예시를 보도록 하겠습니다.
class BigNumberError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return self.message
try:
print("한 자리 숫자 나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요 : "))
num2 = int(input("두 번째 숫자를 입력하세요 : "))
if num1 >= 10 or num2 >= 10:
raise BigNumberError("입력값 : {0}, {1}".format(num1, num2))
print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except ValueError:
print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
except BigNumberError as err:
print("에러가 발생하였습니다. 한 자리 숫자만 입력하세요.")
print(err)
위 코드의 실행 결과는 아래와 같습니다.
C:\Users\Domdomi\Downloads>python custom_exception.py
한 자리 숫자 나누기 전용 계산기입니다.
첫 번째 숫자를 입력하세요 : 10
두 번째 숫자를 입력하세요 : 5
에러가 발생하였습니다. 한 자리 숫자만 입력하세요.
입력값 : 10, 5
직접 BigNumberError 라는 예외처리 전용 클래스를 만들었습니다. 그리고 중요한 것은 이 클래스가 Exception 클래스를 부모 클래스로 상속받고 있다는 사실입니다.
그리고 raise BigNumberError(출력할예외처리내용형식) 에서 예외처리가 발생했을 때 출력할 메시지 내용도 정의 해줄 수 있습니다. 이는 Exception 클래스의 __str__ 메소드를 오버라이딩 해서 사용하고 있기 때문에 가능하게 됩니다.
마지막으로 finally 키워드는 예외처리 발생 시 무조건 실행하고 넘어가야하는 부분을 정의할 수 있는 유용한 키워드 입니다.
try:
print("한 자리 숫자 나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요 : "))
num2 = int(input("두 번째 숫자를 입력하세요 : "))
if num1 >= 10 or num2 >= 10:
raise ValueError
print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except ValueError:
print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
finally:
print("계산기를 이용해 주셔서 감사합니다.")
위 코드를 실행하면 아래와 같습니다. 첫번째로는 정상적인 값을 입력하였을 때이고, 두번째는 잘못된 값을 입력하여 예외처리를 발생시켰습니다.
C:\Users\Domdomi\Downloads>python finally.py
한 자리 숫자 나누기 전용 계산기입니다.
첫 번째 숫자를 입력하세요 : 1
두 번째 숫자를 입력하세요 : 2
1 / 2 = 0
계산기를 이용해 주셔서 감사합니다.
C:\Users\Domdomi\Downloads>python finally.py
한 자리 숫자 나누기 전용 계산기입니다.
첫 번째 숫자를 입력하세요 : a
잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.
계산기를 이용해 주셔서 감사합니다.
위 두 결과를 보면 모두 마지막에 finally 에 정의된 명령들이 올바르게 실행된 것을 확인할 수 있습니다.
'프로그래밍 > Python' 카테고리의 다른 글
[Python] 특정 자료형의 내장함수 찾는 방법 - dir() 함수 (0) | 2021.11.07 |
---|---|
[Python] 모듈(module) 위치 찾는 법 - inspect (0) | 2021.11.07 |
[python] 파이썬으로 날짜가 무슨 요일인지 구하기 (0) | 2021.10.22 |
[pandas] 좌표계 x,y행 모두 다른 좌표계로 변경하는 방법 (0) | 2021.10.21 |
[python] 값 비교하여 증가율, 하락률(%) 알아내기 (전년, 전월대비 등) (0) | 2021.10.20 |