[Python]

파이썬 - 예외처리

AI gina 2022. 5. 25. 10:35

예외

– 프로그램이 실행되는 동안 발생할 수 있는 비정상적인 조건

– 번역시의 에러가 아닌 실행시의 에러 예외라 한다

 

예외 처리

  • 예외 처리 에러가 발생하더라도 스크립트의 실행을 중단시키지 않고 계속 실행하고자 할 때 사용

 

try except 사용하기

  • 예외 처리를 하려면 try에 실행할 코드를 넣고 except 에 예외가 발생했을 때 처리할 코드를 넣는다.             
  • (try의 코드에서 에러가 발생했을 때만 except의 코드가 실행)
    try : 
      실행할 코드 
    except:
      예외가 발생했을 때 처리하는 코드 
a = input('숫자를 입력하세요')

try:
    print('try1')
    int_v = int(a) #형변환을 할 떄 숫자로된 문자가 아니면 형변환 할 수 없다.
    print('try2')  #예외발생하면 그 뒤 블록은 실행되지 않음.
except:
    print('except 1')
    int_v = 10
    print('except 2')
    
print(int_v/3)

print('다음 수행할 일')

print('end!!')
숫자를 입력하세요d
try1
except 1
except 2
3.3333333333333335
다음 수행할 일
end!!

 

 

원하는 예외만 처리하기

  • except 구문에 예외 이름을 지정하면 지정된 예외가 발생했을 때만 처리한다.
try:
    실행할코드
except 예외이름:
    예외가 발생했을 때 처리하는 코드 
  • 예외의 에러 메시지를 받아 올 수 있다.
  • try: 실행할코드 except 예외이름 as 변수: 예외가 발생했을 때 처리하는 코드 print(변수)
  • 모든 예외의 에러 메시지를 출력하고 싶다면 Exception을 이용한다.
except Exception as e:    
    print('예외가 발생했습니다.', e)

예외계층

 

y = [10, 20, 30]
 
try:
    index, x = map(int, input('인덱스와 나눌 숫자를 입력하세요: ').split())
    print(y[index] / x)
except ZeroDivisionError:    # 숫자를 0으로 나눠서 에러가 발생했을 때 실행됨
    print('숫자를 0으로 나눌 수 없습니다.')
except IndexError:           # 범위를 벗어난 인덱스에 접근하여 에러가 발생했을 때 실행됨
    print('잘못된 인덱스입니다.')

 

인덱스와 나눌 숫자를 입력하세요: 4 1
잘못된 인덱스입니다.

 

예외가 발생하지 않았을 때 실행하는 else

  • else구문은 예외가 발생하지 않았을 때 실행할 구문을 기술한다.
  • else는 except 바로뒤에 와야한다.
  • except를 생략 할 수는 없다.
  • 예외가 발생하면 else 구문은 실행되지 않는다.
try:
    실행할 코드
except:
    예외가 발생했을 때 처리하는 코드
else:
    예외가 발생하지 않았을 때 실행할 코드
list_a = [10, 20, 30]
value = 0
 
index = int(input('인덱스를 입력하세요'))

try:
    value = list_a[index]
    print('index로 나눈값은', list_a[index]/index)  #try 실행코드
except Exception as e:
    print(e)                                        #except 블록은 예외가 발생했을때 처리하는 코드
else:
    print("예외가 발생하지 않았을떄 실행되요")      #else 블록은 예외 발생하지 않았을때 처리 코드
finally:
    print('반드시 실행되어야 할 코드를 넣어줘요')   #finally 블록은 항상 실행.
print(value)
print('end')
인덱스를 입력하세요9
list index out of range
반드시 실행되어야 할 코드를 넣어줘요
0
end

 

반드시 실행되는 finally블록

  • 모든 코드가 반드시 실행된다는 보장은 없다.
  • 하지만, 예외가 발생했든 발생하지 않았든 예외를 적절히 처리했든 처리하지 못했든 간에 반드시 처리해야하는 코드들이 있다.
  • finally 블록은 언제든지 실행된다.
  • finally는 except와 else를 생략할 수 있다.
try:
    실행할 코드
except:
    예외가 발생했을 때 처리하는 코드
else:
    예외가 발생하지 않았을 때 실행할 코드
finally:
    예외 발생 여부와 상관없이 항상 실행할 코드

 

사용자가 임의로 예외 발생 시키기

  • python에서 정해놓은 예외 이외에도 사용자의 조건에 맞게 예외를 정의 할 수있다
  • 예외를 발생시킬 때는 raise예외를 지정하고, 에러메시지를 넣는다.
  • 에러메시지는 생략 가능하다.

``` raise 예외 ('에러메시지')

 

 try:
    score = int(input('점수를 입력하세요'))
    if (score>100):
        raise Exception('점수는 100점을 넘을 수 없습니다. 당신이 입력한 값: ', score)
    print(f'당신의 점수는 {score}점 입니다.')
except Exception as e:
    print(e)
점수를 입력하세요400
('점수는 100점을 넘을 수 없습니다. 당신이 입력한 값: ', 400)

 

def inputScore():
    score = int(input('점수를 입력하세요'))
    
    if(score>100):
        raise Exception('점수는 100점을 넘을 수 없습니다. 당신이 입력한 값:',score)
    print(f'당신의 점수는 {score}점 입니다.')
    
try: 
    inputScore()
except Exception as e:
    print(e)
print('end')
점수를 입력하세요200
('점수는 100점을 넘을 수 없습니다. 당신이 입력한 값:', 200)
end

 

현재 예외를 다시 발생 시키기

  • try except 에서 처리한 예외를 다시 발생 시킬 수 있다.
  • except 안에서 raise를 사용하면 현재 예외를 다시 발생 시킨다.
def inputScore():
    score = int(input('점수를 입력하세요'))
try:    
    if(score>100):
        raise Exception('점수는 100점을 넘을 수 없습니다. 당신이 입력한 값:',score)
    print(f'당신의 점수는 {score}점 입니다.')
except Exception as e:
    print('함수가 자체적으로 예외를 처리함')
    print(e)
    raise
     
# inputScore()
try: 
    inputScore()
except Exception as e:
    print('해당 함수를 호출한 쪽에서 예외를 처리함')
    print(e)
print('end')
함수가 자체적으로 예외를 처리함
('점수는 100점을 넘을 수 없습니다. 당신이 입력한 값:', 400)

#raise 예외('에러메시지')

        if x % 3 != 0:
            raise Exception('3의 배수가 아닙니다.')
        print(x)
    except Exception as e:
        print('three_multiple 함수에서 예외가 발생했습니다.', e)
        raise RuntimeError('three_multiple 함수에서 예외가 발생했습니다.')

 

assert로 예외 발생시키기

  • assert는 지정된 조건식이 거짓일 때 assertionError 예외를 발생 시킨다.
  • 조건식이 참이면 그냥 지나간다.
  • assert 는 보통 나와서는 안되는 조건을 검사할 때 사용한다.
x = int(input('3의 배수를 입력하세요'))

assert x % 3 ==0, '3의 배수가 아닙니다'
print(x)
3의 배수를 입력하세요5
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Input In [69], in <cell line: 3>()
      1 x = int(input('3의 배수를 입력하세요'))
----> 3 assert x % 3 ==0, '3의 배수가 아닙니다'
      4 print(x)

AssertionError: 3의 배수가 아닙니다

참고

assert는 디버깅 모드에서만 실행됩니다.

특히 파이썬은 기본적으로 디버깅 모드이며(debug의 값이 True)

assert가 실행되지 않게 하려면 python에 -O 옵션을 붙여서 실행합니다(영문 대문자 O).

python -O 스크립트파일.py

 

 

사용자 정의 예외 만들기

  • 프로그래머가 직접 만든 예외사용자 정의 예외라고 한다.
  • 예외를 생성하는 방법은 Exception을 상속받아서 새로운 클래스를 만들면 된다.
  • 그리고, init 메서드에서 기반 클래스의 init 메서드를 호출한다.
  • 기반클래스의 init메서드를 호출할 때 에러메시지를 넣어준다. 
class 예외이름(Exception):
    def __init__(self):
        super().__init__('에러메시지')
class MyException(Exception):
    def __init__(self):
        supper().__init__('이것은 내가 정의한 예외 객체 입니다')
        

def inputScore():
    score = int(input('점수를 입력하세요'))
    try:    
        if(score>100):
#             raise Exception('점수는 100점을 넘을 수 없습니다. 당신이 입력한 값:',score)
             raise MyException()
        print(f'당신의 점수는 {score}점 입니다.')
    except Exception as e:
        print('함수가 자체적으로 예외를 처리함')
        print(e)
        raise
     
# inputScore()
try: 
    inputScore()
except Exception as e:
    print('해당 함수를 호출한 쪽에서 예외를 처리함')
    print(e)
print('end')
점수를 입력하세요200
함수가 자체적으로 예외를 처리함
name 'supper' is not defined
해당 함수를 호출한 쪽에서 예외를 처리함
name 'supper' is not defined
end