매일공부

[python] 파이썬 예외 처리; try - except - else - finally 본문

Programming/Python

[python] 파이썬 예외 처리; try - except - else - finally

aram 2022. 8. 12. 18:09

- 예외 : 프로그램을 개발하면서 예상하지 못한 상황 발생

- 예측 가능한 예외 : 개발자가 사전에 인지 > 예외 발생 시 어떻게 대응하라고 명시 

- 예측 불가능한 예외 : 프로그램 종료됨 > 매우 많은 파일 처리 시 발생 가능

 

- try except 구문

  • 코드 실행 후 try except문 종료
IndexError 리스트의 인덱스 범위 넘어갈 때 ValueError 변환할 수 없는 문자나 숫자 변환 시
NameError 존재하지 않는 변수 호출 FileNotFoundError 존재하지 않는 파일 호출
ZeroDivisionError 0으로 숫자 나눌 때 TypeError 데이터 유형이 잘못 됐을 때
for i in range(3):
    try:
        print(3/i)
    except ZeroDivisionError as e:  ##출력##
        print(e)                 #division by zero
        print("Not divied by 0") #Not divied by 0
                                 #3.0
                                 #1.5
더보기

Q. 세 개의 정수를 입력받아서 곱을 계산하고 그 결과에서 0~9의 숫자가 몇 개씩 포함되어 있는 지 출력하시오.

[예시]                      [출력 예시]
정수1 입력 : 150    150 x 266 x 427 = 17037300
정수2 입력 : 226     3 1 0 2 0 0 0 2 0 0
정수3 입력 : 427
 
num = []
idx = 0
num_mul = 1
while idx < 3:
    try: 
        num.append(int(input(f'정수 {idx+1} 입력 : ')))
        num_mul *= num[idx]
        idx += 1
    except ValueError as e:
        print(e)

print(f'{num[0]} X {num[1]} X {num[2]} = {num_mul}')

num_mul = str(num_mul)
for i in range(10):
    print(f"{i}:{num_mul.count(str(i))}", end=" / ")

 

- try except else 문

  • 예외 발생x  >  else문 실행
try:
    예외 발생 가능 코드
except 예외 타입:
    예외 발생 시 실행되는 코드
else:
    예외가 발생하지 않았을 때 실행되는 코드
#사용자로부터 정수를 입력을 받아서 짝홀 판단하는 함수 구현 및 실행
num = 0
while True :
    try:
        num = int(input("정수를 입력해주세요(종료 = -1): "))
    except ValueError as e:
        print(e)
        print("정수만 입력해주세요.")
    else:
        if num == -1:
            print("프로그램을 종료합니다.")
            break
        odd_even_check()

 

- try except finally 문

  • finally문 : 예외 발생 여부와 상관없이 반드시 실행되는 코드
  • 사용했던 리소스(자원들)를 정리 작업할 때 주로 사용됨
try:
    예외 발생 가능 코드
except 예외 타입:
    예외 발생 시 실행되는 코드
else:
    예외가 발생하지 않았을 때 실행되는 코드
finally:
    예외 발생 여부와 상관없이 실행되는 코드
def odd_even_check():
    try:
        num = int(input("정수를 입력해주세요: "))
    except ValueError as e:
        print(e)
        print("정수만 입력해주세요.")
    else:
        if num % 2 == 0 :
            print(num, "은 짝수입니다.")
        else :
            print(num, "은 홀수입니다.")
    finally:
        print("홀수와 짝수 판단을 종료합니다")
odd_even_check() #46 은 짝수입니다.
                 #홀수와 짝수 판단을 종료합니다

 

- raise 문

  • 필요할 때 예외를 발생시키는 코드
  • 사용자가 잘못 입력 했을 때 알려주면서 종료
raise 예외 타입(예외 정보)
'''2022년도 중학생 키 값
: 중학생 평균키 범위는 130 이상 180 이하입니다.
: 중학생 평균키 범위를 벗어나는 값은 예외 발생시켜서 작년도 키 평균값으로 보정을 하는 예외처리를 합니다.
Q. 2022년도 중학생 평균 키 값을 출력합니다.'''

#사용자 정의 예외 클래스
class OutOfRangeTallError(Exception):
    def __init__(self, message):
        self.tall = 160.5
        self.message = message
    
    def __str__(self):
        return self.message

#파라미터값의 범위가 130이상 180이하가 아니면 예외(OutOfRangeTall) 발생시킴
def checkTallValue(tall):
    if tall < 130 :
        raise OutOfRangeTallError("중학생 평균키 범위는 130 이상이어야 합니다.")
    elif tall > 180:
        raise OutOfRangeTallError("중학생 평균키 범위는 180 이하이어야 합니다.")

#중학생 키 값
def getMiddleTallAvg(talls):
    """파라미터로 전달받은 중학생 키 값 리스트에서 데이터를 하나씩 유효범위인지 체크해서
    예외가 발생하면 예외클래스의 멤버변수인 작년도 키 값으로 보정을 하는 예외 처리를
    한 후에 올해의 중학생 평균 키를 반환합니다."""
    for idx, t in enumerate(talls):
        try:
            checkTallValue(t)

#as 앞은 단순히 "타입 선언" > class 안의 객체 속성을 사용하려면 객체명 필요. 그게 "e"
        except OutOfRangeTallError as e: 
            print(e)
            print("작년도 중학생 평균키 값으로 보정합니다.")
            talls[idx] = e.tall  #그래서 "OutOfRangeTallError.e"는 안 됨.
    return sum(talls) / len(talls)

talls = [150, 155.5, 148, 117, 161, 163.5, 185, 164, 170, 169, 159, 152]
print("2022년도 중학생 평균 키 :", getMiddleTallAvg(talls))
print(talls)
## 출력 ##
중학생 평균키 범위는 130 이상이어야 합니다.
작년도 중학생 평균키 값으로 보정합니다.
중학생 평균키 범위는 180 이하이어야 합니다.
작년도 중학생 평균키 값으로 보정합니다.
2022년도 중학생 평균 키 : 159.41666666666666
[150, 155.5, 148, 160.5, 161, 163.5, 160.5, 164, 170, 169, 159, 152]

 

- assert 문

  • 미리 알아야 할 예외 정보가 조건 만족x, 예외 발생
  • 잘못된 입력 여부를 사전에 확인 > 나중에 필요 없는 연산을 막아줌
def get_binary_number(decimal_number):
    assert isinstance(decimal_number, int)
    return bin(decimal_number)
print(get_binary_number(10))   #0b1010
print(get_binary_number("10")) #AssertionError Traceback (most recent call last)

## 문자열이 들어오니까 에러 발생

> isinstance(인스턴스, 클래스/데이터타입) : 타입, 클래스, 객체 비교 함수
> bin() : 10진수 숫자를 이진수 문자열로 바꾸는 함수

 

* 내용참고&출처 : 태그의 수업을 복습 목적으로 정리한 내용입니다.

728x90
Comments