서론
어떠한 목적을 가지고 프로그램을 만들 경우 사용자가 정말 무슨 입력을 할지 행동을 할지 모두 예측하는 것은 불가능하다. 그렇기에 코딩을 할 때 예외 사항이 무엇이 있는지 생각해야 하며, 예외가 발생할 수 있는 구문이 생긴다면 아래와 같은 예외처리가 필요하다.
오류
# 예외로 발생한 오류는 디버그에 “exception :”로 나타남
조건문으로 예외
조건문으로도 예외를 처리할 수 있다. 하지만 이 방법은 예외가 발생할 모든 상황을 예측하고 모두 조건문으로 처리해야 하므로 처리하기 힘들다. 아래 예시를 들자면, 정수를 입력하라고 설명이 되어 있지만, 사람들이 숫자를 정수로 넣을지 실수로 넣을지 심지어 영어나 한글로 넣을지 아무도 모른다.
num = int(input("정수를 입력하세요")) #예외가 생길 만한 코드
if num.isdigit(): #isdigit()는 숫자로만 구성되어 있는 자 확인하는 함수이다.
print("원의 둘레: ", 2 * 3.14 * num)
else:
print("정수가 입력되지 않았어요")
예외처리
위 같은 코드는 프로그래머가 모든 상황을 예측할 수 없으므로 아래와 같은 키워드를 이용하여 예외상황을 대비한다.
try :
#예외가 발생할 가능성이 있는 코드
except:
#예외가 발생 했을 때 실행할 코드
else:
#예외가 발생하지 않았을 때 실행할 코드
finally:
#무조건 실행할 코드
try + except
try + except + else
try + except + finally
try + except + else + finally
try + finally
try:
num = int(input("정수를 입력하세요"))
except:
print("정수가 입력되지 않았어요")
else:
print("원의 둘레: ", 2 * 3.14 * num)
finally:
print("오류없이 완료하였습니다.")
예외 객체
예외에는 많은 종류가 있고 클래스로 존재하기에 상속을 받거나 주기도 한다. 아래 더보기에 예외 클래스를 확인할 수 있고 각각 어떠한 의미를 가진 예외들이다.
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
+-- ResourceWarning
어떠한 예외가 발생하는지 직접 지정하여 사용할 수 있다.
try:
#예외가 발생할 가능성이 있는 구문
except 예외의 종류 as 예외 객체를 활용할 변수 이름:
#예외가 발생했을 때 실행할 구문
위 예시를 활용하자면 아래와 같은 코드가 나온다.
try:
num=int(input("정수 입력하세요"))
except ValueError: #데이터 값 오류
print("정수를 입력해 주세요")
else:
print("원의 둘레: ", 2 * 3.14 * num)
모든 예외 잡기
위 코드 또한 모든 예외를 잡은 것이 아니다. 모든 예외를 모두 예측하는 것은 힘들기에 상위 예외 클래스로 다른 예외에 대한 대비를 할 수 있다.
list_num=[32,158,74,12,0]
try:
num=int(input(“정수 입력 :”))
print(“{}번째 요소 : {}”.format(num, list_num[num])))
except ValueError: #데이터 값 오류
print(“정수를 입력해 주세요”)
except IndexError: #잘못된 인덱스로 인덱싱할 때
print(“리스트의 인덱스를 벗어났어요”)
except Exception as exception: #위와 다른 예외 모두 잡기
print(“미리 파악하지 못한 예외 발생”)
print(type(exception),exception) #무슨 예외인지 확인하는 코드
예외 강제 발생
개발하는 동안 ‘이 부분을 그냥 넘어가면 나중에 큰 문제가 발생하니까 여기에서 강제 종료 시키자’라는 경우 혹은 예외 발생 시 처리를 확인하는 경우도 있다. 이때 강제로 예외를 발생시키기도 하는 데 raise키워드를 사용한다. "raise 예외 객체"형태로 예외를 강제 발생한다.
num=int("정수 입력: ")
print("원의 둘레: ", 2 * 3.14 * num)
if num>0:
raise NotImplementedError
else:
raise NotImplementedError
예외 만들기
때때로 내장에 내가 예상되는 상황이 없을 수 있다. 이럴 경우 직접 예외 클래스를 만들기도 한다.
class 예외 이름(Exception): #exception을 상속받아 클래스 생성
def __init__(self):
super().__init__('에러메세지')
class NotThreeMultipleError(Exception):
def __int__(self):
super().__init__('3의 배수가 아닙니다.')
try:
x=int(input('3의 배수를 입력하세요:'))
if x%3!=0:
raise NotThreeMultipleError
print(x)
except Exception as e
print('예외가 발생했습니다', e)
주섬주섬
참고
댓글