티스토리 뷰

728x90
반응형

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

 

Built-in Exceptions — Python 3.10.0 documentation

In Python, all exceptions must be instances of a class that derives from BaseException. In a try statement with an except clause that mentions a particular class, that clause also handles any exception classes derived from that class (but not exception cla

docs.python.org

위 문서는 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 에 정의된 명령들이 올바르게 실행된 것을 확인할 수 있습니다.

728x90
반응형
댓글