파이썬의 예외처리

현서·2025년 7월 8일

파이썬

목록 보기
21/27
post-thumbnail

1. 예외(Exception)

프로그램 실행 중 발생할 수 있는 예상치 못한 문제 또는 오류 상황을 의미.
예외가 발생하면 프로그램은 중단되기 때문에 이를 적절하게 처리하여 중단을 방지하거나 오류에 대한 정보를 사용자에게 제공해야 한다.

print(10 / 3)
print(5 / 0) # ZeroDivisionError: division by zero
print(4 / 2) # 에러난 후, 그 뒤로는 실행이 안 됨.
3.3333333333333335
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
/tmp/ipython-input-1-833358185.py in <cell line: 0>()
      1 print(10 / 3)
----> 2 print(5 / 0) # ZeroDivisionError: division by zero
      3 print(4 / 2) # 에러난 후, 그 뒤로는 실행이 안 됨.

ZeroDivisionError: division by zero

→ 파이썬은 에러 발생 전까지는 실행하고, 에러를 만나면 에러를 출력한다.

2. 예외가 발생하는 경우

  • ValueError
    잘못된 값을 함수나 연산에 제공할 때 발생.
    예) 숫자가 아닌 문자열을 int() 함수로 변환하려고 할 때 발생.

  • TypeError
    올바르지 않은 유형의 객체를 연산에 사용하려 할 때 발생.
    예) 문자열과 숫자를 함께 더하려고 할 때 발생.

  • ZeroDivisionError
    숫자를 0으로 나누려고 할 때 발생.

  • IndexError
    리스트, 튜플, 문자열 등의 시퀀스 유형에서 범위를 벗어난 인덱스에 접근하려 할 때 발생.
    예) 길이가 3인 리스트에 대해 4번째 요소에 접근하려고 할 때 발생.

  • KeyError
    딕셔너리에서 존재하지 않는 키를 사용하여 값을 검색하려고 할 때 발생.

  • AttributeError
    객체에 없는 속성이나 메서드에 접근하려고 할 때 발생.

  • FileNotFoundError
    존재하지 않는 파일을 열려고 할 때 발생.

  • ImportError
    존재하지 않는 모듈을 가져오려고 할 때 또는 모듈 내에 해당 속성/함수가 없을 때 발생.

  • NameError
    정의되지 않은 변수나 함수를 사용하려고 할 때 발생.
    예) 프로그램에서 정의되지 않은 변수 x를 사용하려고 할 때 발생.

  • OverflowError
    수치 연산 결과가 너무 커서 표현할 수 없을 때 발생.

  • MemoryError
    프로그램이 사용 가능한 모든 메모리를 소진했을 때 발생.

3. 예외 처리 기본 구조

try:
    # 예외가 발생할 가능성이 있는 코드
except ExceptionType1:  # 'ExceptionType1'에는 실제 예외 유형이 들어갑니다.
    # ExceptionType1 예외가 발생했을 때 실행될 코드
except ExceptionType2:  # 'ExceptionType2'에는 다른 예외 유형이 들어갑니다.
    # ExceptionType2 예외가 발생했을 때 실행될 코드
# 추가적인 except 블록을 계속 추가할 수 있습니다.
else:
    # try 블록에서 예외가 발생하지 않았을 때 실행될 코드
finally:
    # 예외 발생 여부와 관계없이 항상 실행될 코드
try:
    print(10 / 3)
    print(5 / 0)
    print(4 / 2)
except ZeroDivisionError:
    print('예외가 발생했어요')
print('프로그램을 종료합니다')
3.3333333333333335
예외가 발생했어요
프로그램을 종료합니다

except ZeroDivisionError 대신 except라고만 써도 된다.

try:
    print(10 / 3)
    print(5 / 0)
    print(4 / 2)
except:
    print('예외가 발생했어요')
print('프로그램을 종료합니다')
3.3333333333333335
예외가 발생했어요
프로그램을 종료합니다
try:
    data = [10, 20, 30, 40, 50]
    print(data[0])
    print(data[5])
    print(data[1])
except IndexError:
    print('인덱스 지정이 올바르지 않습니다')
print('프로그램을 종료합니다')
10
인덱스 지정이 올바르지 않습니다
프로그램을 종료합니다
try:
    data = [10, 20, 30, 40, 50]
    # print(data[5])
    # print(int('안녕'))
    print(5 / 0)
except IndexError:
    print('인덱스 지정이 올바르지 않습니다')
except ValueError:
    print('값이 잘 못 입력되었습니다')
except ZeroDivisionError:
    print('0으로 나눌 수 없습니다')
except:
    print('예외가 발생했어요')
print('프로그램을 종료합니다')
0으로 나눌 수 없습니다
프로그램을 종료합니다

각각의 에러 상황에 맞게 출력이 된다.

try:
    data = [10, 20, 30, 40, 50]
    # print(data[5])
    print(int('안녕'))
    # print(5 / 0)
except IndexError as e:
    print(e)
except ValueError as e:
    print(e)
except ZeroDivisionError as e:
    print(e)
except Exception as e:
    print(e)
print('프로그램을 종료합니다')
invalid literal for int() with base 10: '안녕'
프로그램을 종료합니다

에러 문구도 출력이 되었다.

try:
    data = [10, 20, 30, 40, 50]
    print(data[5])
    # print(int('안녕'))
    # print(5 / 0)
except IndexError as e:
    print(e)
except ValueError as e:
    print(e)
except ZeroDivisionError as e:
    print(e)
except Exception as e:
    print(e)
else:
    print('에러가 발생하지 않은 정상적인 프로그램')
finally:
    print('에러에 관계없이 무조건 실행되는 문장')
print('프로그램을 종료합니다')
list index out of range
에러에 관계없이 무조건 실행되는 문장
프로그램을 종료합니다

4. Exception 클래스

파이썬의 내장 예외 계층 구조에서 거의 모든 내장 예외의 기본 클래스.
이 클래스는 사용자 정의 예외를 만들거나 특정 예외 유형을 잡기 위한 기본적인 인터페이스를 제공한다. 예외 유형은 Exception을 상속받아서 정의된다.
예) ValueError, TypeError, FileNotFoundError 등.
이 상속 구조 덕분에 except Exception 블록은 Exception을 상속받은 모든 예외를 처리할 수 있다.

# raise: 예외 상황을 발생시킴
try:
    raise Exception('예외가 발생했어요!!')
except Exception as e:
    print(e)
예외가 발생했어요!!
def func1():
    n = int(input('짝수를 입력하세요: '))
    if n % 2 == 1:
        raise Exception('홀수를 입력했어요!!')
    print(n)
func1()
짝수를 입력하세요: 1
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
/tmp/ipython-input-20-3566840559.py in <cell line: 0>()
----> 1 func1()

/tmp/ipython-input-18-1781302345.py in func1()
      2     n = int(input('짝수를 입력하세요: '))
      3     if n % 2 == 1:
----> 4         raise Exception('홀수를 입력했어요!!')
      5     print(n)

Exception: 홀수를 입력했어요!!
try:
    func1()
except Exception as e:
    print('예외가 발생: ', e)
짝수를 입력하세요: 11
예외가 발생:  홀수를 입력했어요!!
def func1():
    # func2()
    try:
        func2()
    except TypeError:
        print('타입이 올바르지 않습니다')

def func2():
  func3()
  # try:
  #     func3()
  # except TypeError:
  #     print('타입이 올바르지 않습니다')

def func3():
  print('%d' % '문자열')
  # try:
  #     print('%d' % '문자열')
  # except TypeError:
  #     print('타입이 올바르지 않습니다')
# try:
#     func1()
# except TypeError:
#     print('타입이 올바르지 않습니다')
func1()
타입이 올바르지 않습니다

주석처리한 부분 모두 주석을 풀면 예외 처리가 가능하다.

5. 사용자 정의 예외 클래스를 직접 만들고 활용하기

class AgeLimitError(Exception):
    def __init__(self, age, message='MZ세대 나이의 범위가 아님'):
        self.age = age
        self.message = message
        super().__init__(self.message) # Exception('메세지')

def check_age(age):
    if age < 14:
        raise AgeLimitError(age, 'MZ 나이 범위보다 작음')
    elif age > 43:
        raise AgeLimitError(age, 'MZ 나이 범위보다 큼')
    else:
        return f'{age} 나이: MZ 나이 범위안에 포함'
ages = [17, 60, 46, 20, 80, 55, 26, 12, 5]

for age in ages:
    try:
        print(check_age(age))
    except AgeLimitError as e:
        print(f'{e.age} 나이 에러: {e}')
17 나이: MZ 나이 범위안에 포함
60 나이 에러: MZ 나이 범위보다 큼
46 나이 에러: MZ 나이 범위보다 큼
20 나이: MZ 나이 범위안에 포함
80 나이 에러: MZ 나이 범위보다 큼
55 나이 에러: MZ 나이 범위보다 큼
26 나이: MZ 나이 범위안에 포함
12 나이 에러: MZ 나이 범위보다 작음
5 나이 에러: MZ 나이 범위보다 작음
profile
The light shines in the darkness.

0개의 댓글