파이썬 교재 · 12편 / 27편

파이썬 예외 처리 — try·except·finally

에러가 나도 프로그램이 죽지 않게. 입문 단계 마지막 도구.

입문읽는 시간 7분2026-05-13
try/except/finally 로 ValueError 와 KeyboardInterrupt 를 처리하는 코드 화면

사용자에게 나이를 묻고 int() 로 변환하는 코드. 사용자가 "서른" 이라고 입력하면 ValueError 가 빨갛게 뜨고 프로그램이 죽습니다. 파일을 여는데 파일이 없으면 FileNotFoundError, 0 으로 나누면 ZeroDivisionError. 현실 프로그램은 에러가 예외가 아니라 일상이에요. 사용자 입력·파일·네트워크가 끼면 거의 항상 뭔가 어긋납니다.

12편을 마치면 ① try/except 기본 ② 에러 종류로 분기 ③ else·finallyraise 로 직접 발생 ⑤ "함정 — 광범위 except 의 위험" — 5가지로 견고한 프로그램을 짜는 토대.

try·except 기본 구조

# 위험: 잘못된 입력에 죽음
age = int(input("나이: "))   # "서른" 입력 → ValueError → 프로그램 종료

# 안전: try 로 감싸기
try:
    age = int(input("나이: "))
    print(f"내년 {age + 1}살")
except ValueError:
    print("숫자를 입력해주세요")

try 블록 안에서 에러가 나면 즉시 except 로 점프해 처리. 에러가 안 나면 except 는 그냥 건너뜁니다. 두 블록 모두 들여쓰기 4칸으로 묶여요.

중요한 두 가지. ① try 안에서 에러가 난 줄 이후는 실행 안 됩니다. 위에서 int 가 실패하면 print 도 안 나가요. ② except 블록을 지나면 프로그램은 다음 코드로 정상 진행. 에러가 처리됐기 때문.

에러 종류로 분기 — 여러 except

에러는 종류가 매우 많고(파이썬에 약 70개 내장 예외), 각기 다른 처리가 필요합니다.

try:
    with open("config.json") as f:
        data = json.load(f)
    age = int(data["age"])
except FileNotFoundError:
    print("config.json 이 없습니다 — 기본값으로 시작")
except KeyError:
    print("config 에 'age' 키가 없습니다")
except (ValueError, TypeError):    # 튜플로 묶어 여러 종류 한꺼번에
    print("age 값이 숫자가 아닙니다")

except 는 가장 가까운 매치만 잡습니다. FileNotFoundError 가 나면 첫 except 만 실행되고 나머지는 안 거쳐요.

📌 자주 만나는 예외 7종

· ValueError — 자료형은 맞는데 값이 이상 (int("abc"))

· TypeError — 자료형 충돌 ("a" + 1)

· KeyError — dict 에 없는 키

· IndexError — list 범위 밖 인덱스

· FileNotFoundError — 파일이 없음

· ZeroDivisionError — 0 으로 나눔

· KeyboardInterrupt — 사용자 Ctrl+C

else·finally — 흐름 마무리 2 도구

try:
    f = open("data.txt")
    text = f.read()
except FileNotFoundError:
    print("파일 없음")
else:
    print(f"읽은 길이: {len(text)}")    # 예외 안 났을 때만 실행
finally:
    if 'f' in dir():
        f.close()                         # 무조건 실행 — 정리·해제
  • else — try 가 예외 없이 끝났을 때만 실행. "실패하면 건너뛰고, 성공하면 후속 처리" 의도를 명확하게 표현. 정상 흐름과 예외 처리를 시각적으로 분리.
  • finally — 예외가 났든 안 났든 항상 실행. 파일 닫기·DB 연결 해제·리소스 정리 같은 마무리 작업. 함수가 도중에 return 해도 finally 는 실행됩니다.

실무 권장 — with 문이 더 짧음

# 파일 닫기는 with 가 try-finally 보다 간결
with open("data.txt") as f:
    text = f.read()
# 블록 끝나면 자동 close — finally 불필요

# 묶어서
try:
    with open("data.txt") as f:
        text = f.read()
except FileNotFoundError:
    text = ""

13편에서 with 패턴을 정식으로 다룹니다.

raise·광범위 except 의 함정

raise — 직접 예외 일으키기

def divide(a, b):
    if b == 0:
        raise ValueError("0 으로 나눌 수 없습니다")
    return a / b

try:
    divide(10, 0)
except ValueError as e:
    print(f"에러: {e}")    # 에러: 0 으로 나눌 수 없습니다

as e 로 예외 객체를 받아 메시지를 꺼낼 수 있어요. 함수가 잘못된 인자를 받았을 때 명시적 에러를 일으켜 호출자에게 알리는 패턴 — 입문자가 코드 품질을 한 단계 올리는 도구입니다.

⚠️ 절대 피해야 할 패턴 — except 빈손. except: 또는 except Exception: pass 는 모든 에러를 잡아 묻어버립니다. 버그가 일어나도 조용히 진행돼서 1주 뒤에 "왜 잘못된 데이터가 쌓였지" 추적 지옥. 무엇을 처리할지 정확히 알 때 그 종류만 잡으세요.
# ❌ 절대 금지
try:
    risky()
except:
    pass                 # 모든 에러 묵살

# ❌ 좀 낫지만 여전히 위험
try:
    risky()
except Exception:
    pass                 # KeyboardInterrupt 만 제외하고 다 묵살

# ✅ 명시적으로
try:
    risky()
except (ValueError, TypeError) as e:
    log.warning(f"입력 문제: {e}")
    # 의도적 처리 또는 폴백

마무리 — 예외는 흐름의 일부

입문자는 예외를 "에러" 라고만 생각하지만, 파이썬은 예외를 제어 흐름의 도구로도 씁니다. 사용자가 Ctrl+C 를 누르면 KeyboardInterrupt, 반복문에서 더 이상 값이 없으면 StopIteration. "실패할 수 있다" 는 사실을 인정하고 정중하게 처리하는 코드가 실무 파이썬의 절반입니다.

다음 미션 — REPL 에서: ① 입력받은 두 숫자로 나눗셈, 0 또는 비숫자에 안전 ② 파일 읽기 함수에서 없으면 빈 문자열 반환 ③ 본인의 validate_age(age) 함수 — 1~120 외면 ValueError raise.

다음 편 미리보기

13편 — "파이썬 파일 읽기·쓰기": open·with·read·write 패턴과 CSV·JSON 같이 자주 만나는 형식 처리.

📚 27편 파이썬 교재 시리즈 — 12/27편
← 11편 "모듈 import" · 다음: 13편 "파일 읽기·쓰기"

© 2026 주나이테크(주) @JUNAITECH