python/기초

[파이썬 기초] try ~ except문

끼발자 2021. 9. 7. 17:52
반응형

예외처리는 중요하다.

오래 돌려야 하는 코드를 만들다 예상치 못 한 에러에

전부 죽어버릴 수 있으니 이를 미연에 방지해야한다.

 

try ~ except

 

자, 여러분은 지금 두 수를 입력받아서 나누는 코드를 짠다고 생각하자.

a = int(input())
b = int(input())
print( a / b )

간단하게 생각해보면 위와 같이 짤 수 있다.

하지만 만약 입력하는 값이 숫자가 아닌 문자라면?

b가 0이라면?

전자의 경우에는 ValueError, 후자의 경우에는 ZeroDivisionError와 함께 빨간줄이 빠방 하고 나타날 것이다.

 

저주스러운 빨간색보다 이런 에러를 미리 생각해서 부드럽게 print문으로 바꿔줬으면 좋겠다.

이럴 때 사용할 수 있는 메서드가 try문이다.

 

try:
    a = int(input())
    b = int(input())
    print(a/b)
except:
    print('에러가 발생했네요. 입력을 확인해주세요.')

자 이렇게 쓰게되면 input에 문자를 넣기만 하면 바로 에러 발생이라고 출력된다.

 

여기서 좀 의아해진다. 에러가 발생한건 알겠는데,

내가 뭘 잘못했는데 에러가날까?

try:
    a = int(input())
    b = int(input())
    print(a/b)
except Exception as e:
    print(f'에러가 발생했네요. 입력을 확인해주세요. 에러는 {e}입니다.')

자 이렇게 어떤 에러가 발생했는지 명시해주면 어떤 에러인지도 알 수 있다.

하지만, 실제 사용자는 에러코드까지 알고싶지않다.

조금 더 친절하게 접근해보자. 위에서 말했듯, 바로 떠오르는 에러는 ValueError, ZeroDivisionError이므로,

두가지 경우에 각각 다른 출력을 해보자.

try:
    a = int(input())
    b = int(input())
    print(a/b)
except ValueError:
    print('숫자만 입력해주세요')
except ZeroDivisionError:
    print('0으론 나눌 수 없어요.')
except Exception as e:
    print(f'에러가 발생했네요. 입력을 확인해주세요. 에러는 {e}입니다.')

우리는 알고있다. 어떤 에러가 발생할지.

숫자입력되지 않은 에러는 ValueError로 예외처리,

b가 0으로 입력되어 0으로 나눌 수 없는 ZerorDivisionError를 각각 명시해서 다르게 출력하고,

나머지 에러는 예측 밖이니 그냥 출력하는 코드다.

 

특정 에러를 명시해야 디버깅이 수월해진다. 예외처리는 매우매우 유용하게 쓰인다.

반대로 에러를 일으켜보자.

 

try:
    a = int(input())
    b = int(input())
    if a >= 100 or b >=100:
        raise Exception('100보다 큰 숫자는 그냥 싫습니다.')
    print(a / b)
except ValueError:
    print('숫자만 입력해주세요')
except ZeroDivisionError:
    print('0으론 나눌 수 없어요.')
except Exception as e:
    print(f'에러가 발생했네요. 입력을 확인해주세요. 에러는 {e}입니다.')

100보다 큰 숫자가 입력되면 에러를 발생시킨다.

둘중 아무거나 100이상의 값을 넣으면 

에러가 발생했네요. 입력을 확인해주세요. 에러는 100보다 큰 숫자는 그냥 싫습니다.입니다.

 

가 출력된다.

 

포스트가 길어지는 것 같지만 기분탓이다.

 

다음은 finally라는 메서드다.

try안에 예외가 발생할지도 모르는 코드를 작성하고, 

예외가 발생하면 except로 넘어간다면,

finally는 예외발생과 무관하게 실행되는 코드다.

try:
    a = int(input())
    b = int(input())
    if a >= 100:
        raise Exception('100보다 큰 숫자는 그냥 싫습니다.')
    print(a / b)
except ValueError:
    print('숫자만 입력해주세요')
except ZeroDivisionError:
    print('0으론 나눌 수 없어요.')
except Exception as e:
    print(f'에러가 발생했네요. 입력을 확인해주세요. 에러는 {e}입니다.')
finally:
    print('고생했습니다')

 

에러가 발생해도, 발생하지 않아도, 그냥 싫어도 finally 안에 있는 고생했다는 말은 반드시 출력된다.

 

마지막으로 except 안에 raise를 사용해서 예외처리 후에 에러를 발생시킬 수 있다.

def fun():
    try:
        a = int(input())
        b = int(input())
        if a >= 100 or b>=100:
            raise Exception('100보다 큰 숫자는 그냥 싫습니다.')
        print(a / b)
    except ValueError:
        print('숫자만 입력해주세요')
    except ZeroDivisionError:
        print('0으론 나눌 수 없어요.')
    except Exception as e:
        print(f'에러가 발생했네요. 입력을 확인해주세요. 에러는 {e}입니다.')
        raise Exception ###추가
    finally:
        print('고생했슴다')

fun()

 

이렇게 함수 안에 예외처리를 두면, 함수 안에서만 처리되고 상위에서는 정상적으로 작동하게된다.

만약 상위에서 예외처리로 인해 정상적으로 작동되는데, 다른 코드에 영향을 줄 수 있다면

에러코드만 확인하고 에러를 만드는게 더 효과적일 수 있다.

반응형