제로베이스 데이터 취업 파트타임/100일 챌린지_일일 학습 일지

제로베이스 데이터 파트타임 스쿨 학습 일지 [25.04.04]

김뚱입니다 2025. 4. 4. 23:21

[강의 요약]

[Ch 03. 파이썬 중급] 강의 수강

31_finally부터 33_사용자의 Exception 클래스까지 강의 수강하였음

🐢 100일 챌린지 🔥 : [▰▰▰▰▰▰▰▰▰░                                           ] 19/100일 (19%)

수학 공부의 필요성도 느끼는 중

어서 수학 강의로 넘어가서 개념정리를 하고 싶다!

 

 

 

[finally]

  • finally란?
    • finally 구문은 예외 발생 여부와 관계없이 무조건 실행되는 코드 블록임!
    • 예외가 발생해도, 발생하지 않아도 finally 안의 코드는 실행됨
    • 정리 작업이나 로그 출력 등에 사용된다고 한다.

 

 

▶ 예제 코드 : 기본 동작 확인

try:
    inputData = input('input number: ')
    numInt = int(inputData)

except:
    print('exception raise!!')
    print('not number!!')
    numInt = 0

else:
    if numInt % 2 == 0:
        print('inputData is even number!!')
    else:
        print('inputData is odd number!!')

finally:
    print(f'inputData: {inputData}')

이 코드에 10을 입력한다면 이렇게 출력되고

inputData is even number!!
inputData: 10

문자를 입력해서 예외가 발생한다면 이렇게 출력된다.

exception raise!!
not number!!
inputData: 가나다

두 개의 출력 결과를 보면 finally에 있는 print(inputdata)는 무조건 실행된다는 것을 확인할 수 있다!

 

 

 

▶ 실습 코드 : 짝수, 홀수, 실수, 입력값 전부 저장

eveList = []; oddList = []; floatList = []; dataList = []

n = 1
while n < 6:
    try:
        data = input('input number: ')
        floatNum = float(data)

    except:
        print('exception raise!!')
        print('input number again!!')
        continue

    else:
        if floatNum - int(floatNum) != 0:
            print('float number!')
            floatList.append(floatNum)
        else:
            if floatNum % 2 == 0:
                print('even number!')
                eveList.append(int(floatNum))
            else:
                print('odd number')
                oddList.append(int(floatNum))
        n += 1

    finally:
        dataList.append(data)

print(f'eveList: {eveList}')
print(f'oddList: {oddList}')
print(f'floatList: {floatList}')
print(f'dataList: {dataList}')

출력하면 결과는 이렇게 나온다

input number: 가나다
exception raise!!
input number again!!
input number: 3.14
float number!
input number: 0
even number!
...
eveList: [0, 6, 8]
oddList: [3]
floatList: [3.14]
dataList: ['가나다', '3.14', '0', '6', '3', '8']

dataList는 입력값을 무조건 기록하므로 finally의 역할이 야무지다는 것을 확인할 수 있다.

 

 

 

 

[Exception 클래스]

▶ 예외 처리 기본 try ~ except

  •  
  • 프로그램 실행 중 발생하는 예외를 처리하기 위해 사용
  • 예외가 발생해도 프로그램이 중단되지 않고 이어서 실행됨
try:
    print(f'num1 / num2 = {num1 / num2}')
except:
    print('0으로 나눌 수 없습니다.')

 

 

▶ Exception 클래스 사용

  • except Exception as e:
    • 이 형태로 예외 객체를 변수 e에 저장하여 상세한 오류 메시지를 확인할 수 있음
try:
    print(f'num1 / num2 = {num1 / num2}')
except Exception as e:
    print(f'exception: {e}')

출력하면

exception: division by zero

 

 

▶ 예외 종류 구분 처리

  • except ZeroDivisionError, except ValueError 등 구체적인 예외 클래스를 지정하여 더 정교한 예외 처리가 가능
try:
    print(f'num1 / num2 = {num1 / num2}')
except ZeroDivisionError as e:
    print(f'exception: {e}')

 

 

▶ raise 키워드 : 직접 예외 발생

  • raise Exception('오류 메시지')를 통해 예외를 의도적으로 발생시킬 수 있음
  • 이 방식은 사용자 정의 검증 및 경고 처리에 유용하다고 함
def divCalculator(n1, n2):
    if n2 != 0:
        print(f'{n1} / {n2} = {n1 / n2}')
    else:
        raise Exception('0으로 나눌 수 없습니다.')

 

 

▶ 실습 코드 : SMS, MMS 메시지 분기 처리

  • 문자 길이에 따라 예외를 발생시켜 적절한 전송 방식으로 분기
def sendSMS(msg):
    if len(msg) > 10:
        raise Exception('길이 초과!! MMS전환 후 발송!!', 1)
    print('SMS 발송!!')

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

msg = input('input message: ')

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

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

Exception(메시지, 에러코드) 형태다중 정보 전달 가능하고

e.args[0], e.args[1]로 메시지와 코드 각각 접근함

 

 

 

 

[사용자 Exception 클래스]

  • 핵심 개념
    • Exception 클래스를 상속하면 사용자 정의 예외 클래스를 만들 수 있음!
    • 예외 상황을 의미 있는 메시지로 표현하고 싶을 때 유용함
    • raise 키워드로 예외를 발생시키고, try ~ except 구문으로 처리함

 

  • 정리
    • 사용자 정의 예외 클래스는 Exception 상속 후 __init__() 메서드로 메시지를 정의
    • 다양한 예외 유형을 직접 정의함으로써 코드 가독성과 예외 메시지의 명확성을 높일 수 있음

 

 

▶ 예제 코드 : 기본 동작 확인

class NotUseZeroException(Exception):
    def __init__(self, n):
        super().__init__(f'{n}은 사용할 수 없습니다!!')

def divCalculator(num1, num2):
    if num2 == 0:
        raise NotUseZeroException(num2)
    else:
        print(f'{num1} / {num2} = {num1 / num2}')

try:
    num1 = int(input('input number1: '))
    num2 = int(input('input number2: '))
    divCalculator(num1, num2)
except NotUseZeroException as e:
    print(e)

NotUseZeroException 클래스는 0을 나누는 데 사용할 수 없도록 제한하는 역할을 함

 

 

▶ 실습 코드 : 관리자 비밀번호 검증

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

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

class PasswordWrongException(Exception):
    def __init__(self, str):
        super().__init__(f'{str} 잘못된 비밀번호!!')
adminPw = input('input admin password: ')

try:
    if len(adminPw) < 5:
        raise PasswordLengthShortException(adminPw)
    elif len(adminPw) > 10:
        raise PasswordLengthLongException(adminPw)
    elif adminPw != 'admin1234':
        raise PasswordWrongException(adminPw)
    else:
        print('빙고!')

except PasswordLengthShortException as e1:
    print(e1)
except PasswordLengthLongException as e2:
    print(e2)
except PasswordWrongException as e3:
    print(e3)

길이 조건 및 정확성 여부에 따라 서로 다른 예외를 발생시킴

 

 

 

 

[나의 생각 정리]

  • Exception을 상속하면 사용자 정의 예외 클래스를 만들 수 있다.
  • 상황에 맞는 예외 이름과 메시지를 만들어 예외 원인을 명확히 알 수 있다.
  • 조건에 따라 다양한 예외를 구분 처리할 수 있어 유지보수가 편리하다.
  • 사용자 입력이 중요한 프로그램에서 강력한 예외 처리를 구현할 수 있다.

 

 

[적용점]

  • 조건에 따라 특정 입력값을 제한하고 싶을 때?
    • 사용자 정의 예외 클래스를 만들어 raise로 발생시키자
  • 단순 메시지가 아닌, 의미 있는 예외 메시지를 제공하고 싶다면?
    • __init__()을 오버라이드해 상세한 메시지 출력
  • 다양한 예외 상황을 구분해 처리하고 싶다면?
    • 예외 클래스를 여러 개 만들어 except에서 각각 분기
  • 사용자 입력값을 엄격하게 검증하고 싶다면?
    • 사용자 정의 예외로 제어 흐름을 완성하자
  • 시스템에서 공통 예외 외에 도메인 특화 예외를 쓰고 싶다면?
    • Exception을 상속해 새로운 예외 타입을 직접 정의하자

 

 

 

“이 글은 제로베이스 데이터 스쿨 주 3일반 강의 자료 일부를 발췌하여 작성되었습니다.”