예외와 예외처리 클래스

JHKim·2023년 10월 20일
0

Python_study_note

목록 보기
6/7
post-thumbnail

예외(Exception)

문법적인 문제는 없으나, 실행 중 발생하는 예상치 못한 문제를 말한다.

  • 예를 들어, 나눗셈에서 나누는 숫자로 유저가 0을 입력한 경우
    Zero Division Error
  • 에러와는 다르다.
    - 에러란, 소프트웨어가 처리할 수 없는 상태(문법적 문제, 천재지변 등)


예외처리

발생된 예외를 별도 처리해서 전체 프로그램 실행에 문제가 없도록 하는 것

  • 예외가 발생하면 그 이후 코드는 실행이 되지 않는다.
  • 따라서 예외가 발생해도 이후 코드가 실행되도록 처리할 수 있다.

try: ~ except:

  • 예외가 발생할 것으로 예상되는 부분을 try: ~ except:로 감싼다.
  • try:이하를 실행하다가 문제가 발생하면 except:를 실행하게 된다.
  • try:에서 문제가 없다면 except:는 건너뛰고 실행한다.
  • 감싼 부분은 코드블럭으로 들여쓰기!
num = []

while len(num) <= 4:
    try:
        userNum = int(input('Put your Number here: '))
    except:
        print('It\'s not a number! Please enter number.')
        continue

    num.append(userNum)

print(num)

위의 경우, userNumint 처리하도로 되어있지만 str 등이 들어올 수 있기 때문에 예외처리했다.
그리고 except:가 발생하면 continue를 사용해서 다시 조건문으로 돌아가도록 처리했다.

<resule>
Put your Number here: 4
Put your Number here: 243
Put your Number here: 사랑
It's not a number! Please enter number.
Put your Number here: 2
Put your Number here: 1
Put your Number here: 4
[4, 243, 2, 1, 4]

try: ~ except: ~ else:

  • else: 실행문은 예외가 발생하지 않은 경우 실행하는 구문
  • else 쓰려면 tryexcept까지 3개 다 같이 써야 함
  • 꼭 필요하진 않으므로, 상황에 따라 쓰면 된다.

evenList = []; oddList = []; floatList = []

n = 1
while n < 6:
    try:
        num = float(input('Your number: '))
    except:
        print('It\'s not a number. Please enter numbers only.')
        continue   //continue 빼먹지 말기★★★★★★★★★★★★
    
    else:     //없어도 되는 것 같은데... 언제 써야할까...
        if num - int(num) == 0:
            if num % 2 == 0:
                print('Even Number!')
                num = int(num)
                evenList.append(num)
    
            else:
                print('Odd number!')
                num = int(num)
                oddList.append(num)
    
        else:
            print('Float Number!')
            floatList.append(num)

    n += 1

print()
print(f'Even number: {evenList}')
print(f'Odd number: {oddList}')
print(f'Float number: {floatList}')
<result>
Your number: 2
Even Number!
Your number: 14.69
Float Number!
Your number: 100
Even Number!
Your number: 63
Odd number!
Your number: ㅎㅎㅎ
It's not a number. Please enter numbers only.
Your number: 70
Even Number!

Even number: [2, 100, 70]
Odd number: [63]
Float number: [14.69]

finally:

예외 발생하든 안 하든 상관없이 항상 실행하는 실행문

  • 마지막에 꼭 이건 실행해야할 때 사용
  • 외부 자원 가지고 작업할 때 주로 사용. 자원 해제할 때

Exception Class

파이썬의 예외 담당 클래스

  • 사용자가 입력한 except 실행문 외에, 파이썬 에러 종류를 확인하고 싶을 때 사용
  • except Exception as e: 로 닉네임화 해서 사용하면 편리하다.

raise 키워드

  • 강제로 예외를 발생시키고 싶을 때 사용한다.
  • 지금까지는 예외가 발생하면 파이썬에서 예외를 처리했다면, 어떻게 처리할지 사용자가 정할 수 있다.
  • 아래의 경우, division by zero가 아닌 사용자가 정한 메시지로 나온다.

def divCalculator(n1, n2):

    if n2 != 0:
        print(f'{n1} / {n2} = {n1 / n2}')

    else:
        raise Exception('0으로 나눌 수 없습니다.')   
        #지금까지는 파이썬 자체가 예외를 발생시켰다면, 우리가 정하는 것

userNum1 = int(input('number1: '))
userNum2 = int(input('number2: '))
divCalculator(userNum1, userNum2)

여기까지 출력하면 아래와 같이 나온다.

  • raise Exception(a, b)로 매개변수 2개짜리도 발생시킬 수 있다.
  • raise Exception('에러!', 1) 인 경우
    - '에러!': Exception.args[0]
    - 1: Exception.args[1]

def sendSMS(msg):

    if len(msg) > 10:
        raise Exception('길이 초과! MMS로 전환 후 발송.', 1)

    else:
        print('SMS 발송 완료!')

def sendMMS(msg):
    if len(msg) <= 10:
        raise Exception('길이 미달! SMS로 전환 후 발송.', 2)

    else:
        print('MMS 발송 완료!')

msg = input('문자 입력: ')

try:
    sendSMS(msg)

except Exception as e:
    print(f'{e.args[0]}')
    print(f'{e.args[1]}')

    if e.args[1] == 1:
        sendMMS(msg)
    elif e.args[1] == 2:
        sendMMS(msg)

raise Exception('길이 초과! MMS로 전환 후 발송.', 1)로 처리하여
실행문에서 예외가 발생했을 때 분기 처리하여 다른 실행문을 실행하도록 처리할 수 있다.
if e.args[1] == 1: sendMMS(msg)이기 때문에 sendMMS()가 자동 실행된 것.

<result1>
문자 입력: 집에 가고 싶다
SMS 발송 완료!

<result2>
문자 입력: 만날 수 없어 만나고 싶은데 그런 슬픈 기분인걸
길이 초과! MMS로 전환 후 발송.
1
MMS 발송 완료!

사용자 예외 클래스

예외 클래스도 클래스이기 때문에 클래스 자체를 내가 만들 수 있다.

  • 파이썬의 Exception 클래스를 상속하면 됨
  • 실제 프로그래밍에 자주 쓰인다.

class PWLengthShortException(Exception):

    def __init__(self, str):
        super().__init__(f'{str}: 길이 5 미만!!')

class PWLengthLongException(Exception):

    def __init__(self, str):
        super().__init__(f'{str}: 길이 10 초과!!')

class PWWongException(Exception):

    def __init__(self, str):
        super().__init__(f'{str}: 잘못된 비밀번호!!')


i = 0
while i < 5:   # 5회 이상 입력 시 입력 중단하려고 추가함
    userPW = input('비밀번호 입력: ')
    i += 1

    try:
        if len(userPW) < 5:
            raise PWLengthShortException(userPW)

    except PWLengthShortException as e1:  
    # except 여러 번 쓸 수 있음
        print(e1)
        continue

    try:
        if len(userPW) > 10:
            raise PWLengthLongException(userPW)
    except PWLengthLongException as e2:
        print(e2)
        continue

    try:
        if userPW != 'admin1234':
            raise PWWongException(userPW)
    except PWWongException as e3:
        print(e3)
        continue

    if userPW == 'admin1234':
        print('빙고!')
        break

else:
    print('입력 횟수 초과')
<result>
비밀번호 입력: 13
13: 길이 5 미만!!
비밀번호 입력: sdlkfjsa
sdlkfjsa: 잘못된 비밀번호!!
비밀번호 입력: seflk
seflk: 잘못된 비밀번호!!
비밀번호 입력: sd;l
sd;l: 길이 5 미만!!
비밀번호 입력: admin1234
빙고!

0개의 댓글