python - exception class

slocat·2023년 11월 13일
0

start-data

목록 보기
11/75

예외란

문법적인 문제가 아니라 실행 중에 발생할 수 있는 문제이다.
예외 관련 클래스는 Exception 클래스를 상속한다.

try ~ except ~ else ~ final

try:
    data = input('숫자 입력: ')
    intData = int(data)
    
# 예외가 발생하면 실행
except:
    print('숫자가 아닙니다.')

# 예외가 발생하지 않으면 실행    
else:
    print('OK! 숫자를 입력했습니다.')
    
# 예외 발생 여부와 무관하게 항상 실행
finally:
    print(f'inputData = {data}')

Exception as e

n1 = 10
n2 = 0

try:
  print(n1 / n2)
except Exception as e:
  print(e)

>>>
division by zero

raise : 예외 발생시키기

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 = '길이가10을초과하는메시지입니다'

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

  if e.args[1] == 1:
    sendMMS(msg)
  elif e.args[1] == 2:
    sendSMS(msg)
    
>>>
예외 발생(1): 길이 초과 - MMS로 발송됩니다.
MMS 발송

왜 e[0]이 아니라 e.args[0]로 써야할까?
🔅https://docs.python.org/3/tutorial/errors.html

print(e.args)	# arguments stored in .args
print(e)		# __str__ allows args to be printed directly,
				# but may be overridden in exception subclasses

사용자 예외 클래스 만들기

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


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


class WrongException(Exception):
    def __init__(self, pw):
        super().__init__(f'{pw}: 잘못된 비밀번호')


def login(inputPw):
    pw = '1234567'

    if len(inputPw) < 5:
        raise ShortException(inputPw)
    elif len(inputPw) > 10:
        raise LongException(inputPw)
    elif pw != inputPw:
        raise WrongException(inputPw)
    else:
        print('비밀번호가 일치합니다.')


inputPw = input('비밀번호를 입력하세요: ')

try:
    login(inputPw)
except Exception as e:
    print(e)
    
>>>
비밀번호를 입력하세요: 123
123: 길이 5 미만
>>>
비밀번호를 입력하세요: 123456789123
123456789123: 길이 10 초과
>>>
비밀번호를 입력하세요: 12345678
12345678: 잘못된 비밀번호
>>>
비밀번호를 입력하세요: 1234567
비밀번호가 일치합니다.   

globals() ❓

# 풀이 중에서...

for g in gcsDic.keys():
    totalPrice += globals()[f'{g}Price'] * gcsDic[g]

globals() 함수는 모듈 내의 전역변수에 대한 정보를 알고 싶을 때 사용한다.

def local():
    a = 1
    b = 2
    print(f'Local Variable: {locals()}') # 딕셔너리 출력

local()

a = 3
c = 4
print(f'Global Variable: {globals()}') # 딕셔너리 출력
print(globals()['a']) # 전역변수 딕셔너리에서 key='a'인 아이템 출력

globals()['a'] = 30 # 값 수정
print(globals()['a'])

>>>
Local Variable: {'a': 1, 'b': 2}
Global Variable: {'__name__': '__main__', ... , 'a': 3, 'c': 4}
3
30

예외처리 문제풀이 3

모듈로 만드는 게 익숙하지 않아서 선생님의 답과 다른 경우가 많다.😂

priceGoods = {1: 100, 2: 200, 3: 300, 4: 400, 5: 500}
purchaseGoods = {}
notPurchaseGoods = {}

for i in range(1, 6):
    try:
        inputNum = input(f'goosd{i} 구매 개수: ')
        purchaseGoods[i] = int(inputNum)
    except Exception as e:
        print(e)
        notPurchaseGoods[i] = inputNum

totalPrice = 0
for key in purchaseGoods.keys():
    totalPrice += purchaseGoods[key] * priceGoods[key]

print(f'총 구매 금액: {totalPrice}원')
for key in notPurchaseGoods.keys():
    print(f'잘못 입력했습니다.({key}번 상품: {notPurchaseGoods[key]})')
# 답지
g1Price = 100; g2Price = 100; g3Price = 100
g4Price = 100; g5Price = 100

# 실행 파일에서 g1Cnt, g2Cnt, ... 넘겨줌
# gcs = 튜플
def calculator(*gcs):
    gcsDic = {}
    againCntInput = {}

    for idx, gc in enumerate(gcs):
        try:
            gcsDic[f'g{idx+1}'] = int(gc)
        except Exception as e:
            againCntInput[f'g{idx+1}'] = gc
            print(e)

    totalPrice = 0
    for g in gcsDic.keys():
        totalPrice += globals()[f'{g}Price'] * gcsDic[g]

    print(f'{totalPrice}')
    (...)

예외처리 문제풀이 4

# 예외 클래스
class EmptyException(Exception):
    def __init__(self, i):
        super().__init__(f'{i} is empty.')

def joinCheck(n, m, p, a, ph):
    if n == '':
        raise EmptyException('name')
    elif m == '':
        raise EmptyException('mail')
    elif p == '':
        raise EmptyException('pw')
    elif a == '':
        raise EmptyException('address')
    elif ph == '':
        raise EmptyException('phone')
    else:
        print('Membership completed!')

class RegistMember():
    def __init__(self, n, m, p, a, ph):
        pass

    def printMemberInfo(self):
        pass

# ✨실행 파일
import join

try:
    join.joinCheck(name, mail, pw, address, phone)
    member = join.RegistMember(name, mail, pw, address, phone)
    member.printMember()
except join.EmptyException as e:
    print(e)

>>>
이름 입력: 꼬미
메일 입력: ggomi@gmail.com
비밀번호 입력: 1234
주소 입력: 
연락처 입력: 01012345678
address is empty.

예외처리 문제풀이 5

import random

class LackException(Exception):
    def __init__(self, accountM, money):
        super().__init__(f'잔고 부족 [잔액: {accountM}, 출금액: {money}]')

class Bank:
    def __init__(self):
        self.accounts = {}

    def addAccount(self, account):
        self.accounts[account.no] = account

    def isAccount(self, no):
        return no in self.accounts

    def doDeposit(self, no, money):
        account = self.accounts[no]
        account.money += money

    def doWithdraw(self, no, money):
        account = self.accounts[no]
        if account.money < money:
            raise LackException(account.money, money)
        else:
            account.money -= money

class Account:
    def __init__(self, bank, name):
        self.bank = bank
        self.name = name

        # 계좌번호 생성
        while True:
            newNo = random.randint(10000, 99999)
            if bank.isAccount(newNo):
                continue
            else:
                self.no = newNo
                break

        self.money = 0
        bank.addAccount(self)

    def printAccountInfo(self):
        print('-' * 50)
        print(f'name: {self.name}')
        print(f'no: {self.no}')
        print(f'money: {self.money}원')
        print('-' * 50)

# ✨실행 파일
import bank

koreaBank = bank.Bank()

myName = input('통장 개설을 위한 예금주 입력 > ')
myAccount = bank.Account(koreaBank, myName)
myAccount.printAccountInfo()

while True:
    inputNum = int(input('1.입금  2.출금  3.종료 > '))

    if inputNum == 1:
        money = int(input('입금액 입력 > '))
        koreaBank.doDeposit(myAccount.no, money)
        myAccount.printAccountInfo()

    if inputNum == 2:
        try:
            money = int(input('출금액 입력 > '))
            koreaBank.doWithdraw(myAccount.no, money)
            myAccount.printAccountInfo()

        except bank.LackException as e:
            print(e)
            myAccount.printAccountInfo()

    if inputNum == 3:
        print('거래를 종료합니다.')
        break

0개의 댓글