728x90
반응형
예외란?
- 프로그램 실행 도중 발생하는 문제
- 적절한 처리를 통해 프로그램이 종료되는걸 막을 수 있음
- 오류 원인을 사용자에게 알려줄 수 있음.
1. 오류의 종류
- Syntax Error: 문법 오류(코드 실행 전 발견).
- Exception: 실행 중 발생하는 오류(예: TypeError, ValueError, ZeroDivisionError 등).
# SyntaxError 예시는 실행 불가(주석으로 표기)
# print("missing quote) # -> SyntaxError: EOL while scanning string literal
# Exception 예시: 실행 중 발생 (포착해서 출력)
try:
x = 1 + "a"
except TypeError as e:
print("TypeError:", e)
## 출력: TypeError: unsupported operand type(s) for +: 'int' and 'str'
2. 자주 볼 수있는 내장 예외
| 예외 유형 | 의미 | 주요 상황 발생 예시 |
| TypeError | 지원되지 않는 데이터 타입 간의 연산이나 잘못된 타입의 인자를 전달할 때 발생 | 1 + '2' (숫자와 문자열 덧셈), len(5) |
| NameError | 정의되지 않은 변수나 함수 이름을 참조할 때 발생 | print(x) (x가 정의되지 않음) |
| IndexError | 리스트나 튜플 등 시퀀스의 인덱스가 범위를 벗어날 때 발생 | arr = [1, 2]; arr[5] |
| KeyError | 딕셔너리에서 존재하지 않는 키로 접근할 때 발생 | d = {'a': 1}; d['b'] |
| ValueError | 인자의 타입은 맞지만 값이 부적절할 때 발생 | int('abc'), [1, 2].remove(3) |
| FileNotFoundError | 존재하지 않는 파일을 열거나 접근하려 할 때 발생 | open('nofile.txt') |
| ZeroDivisionError | 0으로 나누기를 시도할 때 발생 | 10 / 0 |
# NameError
try:
print(unknown_var)
except NameError as e:
print("NameError:", e)
# IndexError
try:
a = [1,2]
print(a[5])
except IndexError as e:
print("IndexError:", e)
# KeyError
try:
d = {'a':1}
print(d['b'])
except KeyError as e:
print("KeyError:", e)
# ZeroDivisionError
try:
print(1/0)
except ZeroDivisionError as e:
print("ZeroDivisionError:", e)
## 출력 예시:
# NameError: name 'unknown_var' is not defined
# IndexError: list index out of range
# KeyError: 'b'
# ZeroDivisionError: division by zero
3. 예외 강제로 발생 시키기
- raise: 원하는 시점에 예외를 발생시킬 때 사용.
- assert: 조건이 거짓이면 AssertionError 발생(주로 디버깅/도메인 검증).
# raise 사용
def check_positive(x):
if x < 0:
raise ValueError("x must be >= 0")
try:
check_positive(-5)
except ValueError as e:
print("Raised ValueError:", e)
## 출력: Raised ValueError: x must be >= 0
# assert 사용
def ensure_nonzero(x):
assert x != 0, "x must not be zero"
try:
ensure_nonzero(0)
except AssertionError as e:
print("AssertionError:", e)
## 출력: AssertionError: x must not be zero
4. try / except / else / finally
- except에는 특정 예외를 명시하자.
- else: 예외 없을 때 실행.
- finally: 항상 실행(리소스 정리).
try:
val = int("123")
except ValueError as e:
print("ValueError:", e)
else:
print("Conversion succeeded:", val)
finally:
print("Always runs (cleanup if needed)")
# 강제로 에러 발생시 여러 except 처리
try:
result = 10 / 0
except ZeroDivisionError as e:
print("Handled ZeroDivisionError:", e)
except Exception as e:
print("Other Error:", e)
finally:
print("Done")
## 출력:
# Conversion succeeded: 123
# Always runs (cleanup if needed)
# Handled ZeroDivisionError: division by zero
# Done
5. 사용자 정의 예외 (커스텀)
- 내장 Exception을 상속하여 명확한 에러 타입을 만든다.
- __init__으로 추가 정보 저장 가능.
class ValueTooHighError(Exception):
pass
class ValueTooSmallError(Exception):
def __init__(self, message, value):
super().__init__(message)
self.value = value
def test_value(x):
if x > 100:
raise ValueTooHighError("Value is too high")
if x < 0:
raise ValueTooSmallError("Value is too small", x)
return x
# 사용
try:
test_value(150)
except ValueTooHighError as e:
print("Custom error:", e)
try:
test_value(-3)
except ValueTooSmallError as e:
print("Custom error:", e, "| value:", e.value)
## 출력:
# Custom error: Value is too high
# Custom error: Value is too small | value: -3
******* 참고 *****
- 가능한 특정 예외를 잡는 것이 좋다 (except ValueError:)
- 불필요한 except 는 디버깅을 하는데 어려움을 줄 수 있음
- 명확한 예외 로직에 로그를 남기고 사용자에게 명확한 메시지를 제공할 수 있는 것이 좋다.
728x90
반응형
'프로그래밍 > Python' 카테고리의 다른 글
| [파이썬 / 기본] Random 라이브러리 (0) | 2025.12.01 |
|---|---|
| [파이썬 / 기본] Logging (0) | 2025.10.24 |
| [파이썬 / 기본] Lambda Function (0) | 2025.10.22 |
| [파이썬 / 기본] itertools (0) | 2025.10.21 |
| [파이썬 / 기본] collections (0) | 2025.10.20 |