이번에는 파이썬에서의 예외처리를 학습하면서 실제로 다양한 예외처리 구문을 작성해 보았습니다. 코드가 비정상적으로 중단되지 않고, 예상하지 못한 오류에 대해 대처할 수 있는 방법을 알아 보았습니다.
try:
print("한 자리 숫자 나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요 :"))
num2 = int(input("두 번째 숫자를 입력하세요 :"))
if num1 >= 10 or num2 >= 10:
raise ValueError
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
여기서 ValueError
와 ZeroDivisionError
같은 예외들을 처리할 수 있도록 하였습니다. 예를 들어 숫자가 아닌 값을 입력하거나, 0으로 나누기를 시도했을 때 적절한 예외 메시지를 출력합니다.
특정 조건에서 에러를 직접 발생시킬 수도 있습니다. 예를 들어, 한 자리 숫자만 입력할 수 있는 계산기를 만들 때, 두 자리 이상의 숫자가 입력되면 (ex : 10) 의도적으로 ValueError를 발생시킬 수 있습니다.
try:
print("한 자리 숫자 나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요 :"))
num2 = int(input("두 번째 숫자를 입력하세요 :"))
if num1 >= 10 or num2 >= 10:
raise ValueError
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
print("잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.")
이 코드를 통해 두 자리 이상의 숫자가 입력되면 ValueError가 발생하며, 사용자에게 입력이 잘못 되었다는 것을 알립니다.
파이썬에서는 사용자 정의 예외를 만들 수 있습니다. 이를 통해 특정 상황에서 발생할 수 있는 예외를 더 명확하게 처리할 수 있습니다.BigNumberError
라는 예외를 정의하고, 두 자리 숫자가 입력되었을 때 이 예외를 발생시키도록 했습니다.
class BigNumberError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
try:
print("한 자리 숫자 나누기 전용 계산기입니다.")
num1 = int(input("첫 번째 숫자를 입력하세요 :"))
num2 = int(input("두 번째 숫자를 입력하세요 :"))
if num1 >= 10 or num2 >= 10:
raise BigNumberError("입력값 : {0}, {1}".format(num1, num2))
print("{0} / {1} = {2}".format(num1, num2, int(num1 / num2)))
except BigNumberError as err:
print("에러가 발생하였습니다. 한 자리 숫자만 입력하세요.")
print(err)
finally:
print("계산기를 이용해 주셔서 감사합니다.")
이 코드는 사용자 정의 예외를 발생시킬 뿐만 아니라, finally 구문을 통해 예외가 발생하든 발생하지 않든 항상 마지막에 특정 동작을 수행할 수 있게 해줍니다.
첫 번째 숫자를 입력하세요 : 5
두 번째 숫자를 입력하세요 : 2
5 / 2 = 2
계산기를 이용해 주셔서 감사합니다.
첫 번째 숫자를 입력하세요 : 10
두 번째 숫자를 입력하세요 : 2
에러가 발생하였습니다. 한 자리 숫자만 입력하세요.
입력값 : 10, 2
계산기를 이용해 주셔서 감사합니다.
첫 번째 숫자를 입력하세요 : "열개"
잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요.
계산기를 이용해 주셔서 감사합니다.
주어진 코드에서 적절한 예외처리 구문을 추가하여, 치킨 주문 시스템을 만들었습니다. 예외 처리 없이 시스템이 작동하면 비정상적인 값이 입력되었을 때 오류가 발생하여 프로그램이 중단될 수 있기 때문에, 다양한 예외를 처리할 수 있도록 구현했습니다.
ValueError
로 처리.SoldOutError
를 발생시켜 프로그램 종료.
chicken = 10
waiting = 1 # 홀 안에는 현재 만석, 대기번호 1부터 시작
while(True):
print("[남은 치킨 : {0}]".format(chicken))
order = int(input("치킨 몇 마리 주문하시겠습니까?"))
if order > chicken:
print("재료가 부족합니다.")
else:
print("[대기번호 {0}] {1} 마리 주문이 완료되었습니다.".format(waiting, order))
waiting += 1
chicken -= order
이 코드는 문제에 주어진 기본적인 주문 시스템입니다.
퀴즈 문제에 대한 답안 코드를 통해, 사용자 정의 예외인 SoldOutError
를 추가하고 예외처리 를 넣었습니다.
chicken = 10
waiting = 1 # 홀 안에는 현재 만석, 대기번호 1부터 시작
class SoldOutError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
try:
while(True):
if chicken == 0:
raise SoldOutError("재고가 소진되어 더 이상 주문을 받지 않습니다.")
print("[남은 치킨 : {0}]".format(chicken))
order = int(input("치킨 몇 마리 주문하시겠습니까?"))
if order > chicken: # 남은 치킨보다 주문량이 많을 때
print("재료가 부족합니다.")
elif order <= 0:
raise ValueError
else:
print("[대기번호 {0}] {1} 마리 주문이 완료되었습니다.".format(waiting, order))
waiting += 1
chicken -= order
except ValueError: #조건 1 try, except 구문 추가.
print("잘못된 값을 입력하였습니다.")
except SoldOutError as err:
print(err)
class SoldOutError(Exception):
pass
while(True):
try:
print("[남은 치킨 : {0}]".format(chicken))
order = int(input("치킨 몇 마리 주문하시겠습니까?"))
if order > chicken: # 남은 치킨보다 주문량이 많을 때
print("재료가 부족합니다.")
elif order <= 0:
raise ValueError
else:
print("[대기번호 {0}] {1} 마리 주문이 완료되었습니다.".format(waiting, order))
waiting += 1
chicken -= order
if chicken == 0:
raise SoldOutError
except ValueError: #조건 1 try, except 구문 추가.
print("잘못된 값을 입력하였습니다.")
except SoldOutError:
print("재고가 소진되어 더 이상 주문을 받지 않습니다.")
break
먼저 나는 SoldOutError
를 정의하면서 메시지(msg)
를 받아서, 예외가 발생할 때 이 메시지를 출력할 수 있도록 하고 싶었다. 예외가 발생했을 때 __str__
메서드가 호출되어 메시지를 출력하게 된다.
그러나
모범 답안(강의中)은 SoldOutError
클래스에 추가적인 메서드나 메시지가 없으며, 단순히 예외를 발생시키고, 메시지는 예외 처리 블록에서 처리하고 있었다.
내 답안에서는 치킨이 0이 되면 예외를 발생시키고, 예외 처리 블록에서 오류 메시지를 출력한 후에도 프로그램이 계속 실행된다 ㅠㅠ...
모범 답안에서는 치킨이 0이 되어 SoldOutError
가 발생하면 break
를 통해 반복문을 종료하도록 되어 있습니다.
아직 반복문의 break
에 숙달되지 않은 것 같다.
또한 예외 구문 처리에서도 내 코드는 예외 클래스에서 받은 메시지를 출력하는 방식으로 처리하고 있지만, 이로 인해 코드가 복잡해졌다. 특히, 메시지가 고정되어 있는 경우에는 모범 답안처럼 except
블록에서 직접 메시지를 출력하는 것이 더 간단하고 효율적으로 보인다.