TIL python 예외처리

0

TIL

목록 보기
6/29

Python 문법

예외처리

말그대로 예외가 발생할 때 처리하는 것과 더불어 예외를 직접 발생시키는 경우도 포함한다.
프로그래밍이 끝없는 디버그와 싸우는 상황이기 때문에 예외들 (혹은 에러들)을 파악하는 것은 중요하다.

지피지기면 백전백승이라 하지 않는가?

항상 이기지는 못하더라도 날 괴롭히는 대상이 누군지는 알아야 하지 않겠는가?

예외처리 try/ except

try:
-----시도하는 식
except:
----- try 식 시도 중에 예외가 발생할 때 처리할 식

try:
	def ten_div(x):
    	return 10/x
except:
	print("0으로 나눌 수 없습니다")
  • try로 내가 쓰고자 하는 식을 적용한다.
  • try 도중에 error가 발생하면 except 문을 실행한다.
  • 위에 식에서 x=0이라면 10을 0으로 나누는 문제가 발생한다.
    ZeroDivisionError: division by zero
  • 특정 에러가 발생할 때 행동을 지정할 수 있다.
    try:
    	def ten_div(x):
       	return 10/x
    except ZeroDivisionError:
    	print("0으로 나눌 수 없습니다")
       
  • except errorname as e:
    print(e)를 한다면 어떤 에러가 발생했는지 에러메시지를 확인할 수 있다.
try:
	def ten_div(x):
    	return 10/x
except ZeroDivisionError as e :
	print("0으로 나눌 수 없습니다 ", e) 
  • x= 0 입력한 경우
    < 0으로 나눌 수 없습니다 ZeroDivisionError: division by zero> 출력

하지만 모든 에러를 알 수 없기 때문에 일일이 지정하는 것은 어렵고 더욱이 모든 예외를 다 작성해야 하기 때문에 비효율적이다.

Error Hierarchy

이때 알아야 하는 것이 ERROR도 클래스라는 것이다.


출처: 대표적인 파이썬 error hierarchy

위에 이미지에서 알 수 있듯이 각 에러는 하나의 클래스이고 상위 클래스의 속성을 상속받는다.
예) zero Division error ⊂ Arithmetic Error ⊂Standard error ⊂ Exception ⊂ BaseException
(! 상속의 정확한 표현이 아니다 - 참고용 부분집합기호 )

따라서 표현을 할 떄

except ZerpDivisionError 대신에
except BaseException을 입력하면 더 많은 에러의 경우를 포함할 수 있다.

다만 이를 쓸 때 조심해야 하는 것은 에러 표시는 파생(하위)클래스보다 높은 기반(상위)클래스가 있을 때 에러가 표출된다는 것이다.

예를 들어서

만약 ZeroDivisionError와 RuntimeError에러가 동시에 발생했다면 이 때는 RuntimeError만 표출된다.

else finally

try:
except:
else:
finally:

조건문에 if else가 있듯이 예외처리에도 else가 있다. 예외처리에서의 else의 경우 예외가 발생할 때 실행된다.

여기에 finally예외 여부와 상관없이 무조건적으로 실행된다.

raise error 에러 일으키기

raise error --> 주체적으로 에러를 일으키는 것이다
error occur--> 에러가 스스로 발생한 것

try 내부에서 에러 정의하기


try: 
	if x%3 != 0:
    		raise Exception ('3의 배수가 아닙니다')
    	print(x)
        
except Exception as e:
	print('exception occur', e)
   

클래스로 에러 미리 정의하고 일으키기

  • 에러가 클래스인 점을 이용 미리 에러 클래스 정의하기
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('exception occur', e)
        
        
three_multiple()

assert

assert == if +raise

  • 조건이 false일 때 에러 일으키는 역할
  • 디버깅 모드에서만 가능하지만 파이썬은 기본 디버깅 모드!
x= int(input('multiple of 3'))
assert x % 3 == 0, 'not multiple of 3 error'
print(x)
  • 출력 : AssertionError: not multiple of 3 error

try except 알고리즘 적용

실제 알고리즘 문제를 풀다가 try except 개념이 적용된 문제가 있어서 같이 적어놓기로 한다.

  1. 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
  • 입력
    첫째 줄에 테스트 케이스의 개수 T가 주어진다.
    각 테스트 케이스는 한 줄로 이루어져 있으며,
    각 줄에 A와 B가 주어진다. (0 < A, B < 10)
  • 출력
    각 테스트 케이스마다 A+B를 출력한다.
  • 예제 입력 1
    5
    1 1
    2 3
    3 4
    9 8
    5 2
  • 예제 출력 1
    2
    5
    7
    17
    7
  1. 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
  • 입력
    입력은 여러 개의 테스트 케이스로 이루어져 있다.
    각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
  • 출력
    각 테스트 케이스마다 A+B를 출력한다.
  • 예제 입력 1
    1 1
    2 3
    3 4
    9 8
    5 2
  • 예제 출력 1
    2
    5
    7
    17
    7
  1. 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
  2. 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

처음 봤을 때 이 두 문제의 차이는 없어보였다... 분명 다른 문제인데

차이점은 입력 부분이었다.
1. 입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다.
2. 입력
입력은 여러 개의 테스트 케이스로 이루어져 있다.

즉 입력케이스의 숫자가 주어지냐 아니냐에 따라 차이가 나는 것인데....여기서 어떻게 try except의 개념이 적용되는가 살펴봐야겠다.

1번째 같은 경우 테스트 케이스 입력된 경우에만 맞으면 되지만 ex) 3--> 3번의 경우에만 맞으면 오케이!

2번째 같은 경우 어떤 것이 입력되더라도 출력이 되어야 하기 때문에 try except로 예외처리까지 해줘야 제대로 푼 문제라고 할 수 있다.

profile
기록을 통해 한 걸음씩 성장ing!

0개의 댓글