Python은 try/except 블록과 선택적 else, finally로 오류를 처리합니다. Python은 EAFP 원칙 — "허락보다 용서를 구하는 것이 쉽다(Easier to Ask Forgiveness than Permission)" — 을 채택하여, 먼저 조건을 확인하기보다 연산을 시도하고 예외를 처리하는 것을 선호합니다.
Python은 try/except 블록과 선택적 else, finally로 오류를 처리합니다. Python은 EAFP 원칙 — "허락보다 용서를 구하는 것이 쉽다(Easier to Ask Forgiveness than Permission)" — 을 채택하여, 먼저 조건을 확인하기보다 연산을 시도하고 예외를 처리하는 것을 선호합니다.
try:
result = risky_operation()
except ValueError as e: # 특정 예외 타입을 잡음
print(f"bad value: {e}")
except (KeyError, IndexError): # 여러 타입을 잡음
print("lookup failed")
except Exception as e: # 포괄 처리 (드물게 사용, 마지막에)
print(f"unexpected: {e}")
else:
print("예외가 발생하지 않은 경우에만 실행됨")
finally:
cleanup() # 항상 실행됨 (성공이든 실패든)
except SpecificError — 특정 타입을 잡음 (포괄 처리보다 선호됨).else — 예외가 발생하지 않은 경우에만 실행됨.finally — 예외가 전파되더라도 항상 실행됨 (정리, 자원 해제).# LBYL ("Look Before You Leap") — 먼저 확인
if key in my_dict:
value = my_dict[key]
# EAFP ("Easier to Ask Forgiveness") — 시도하고 실패를 처리 — 더 Pythonic함
try:
value = my_dict[key]
except KeyError:
value = default
Python은 관용적으로 EAFP를 선호합니다 — 연산을 시도하고 예외를 잡는 것 — 이는 경쟁 상태를 피하고 종종 사전 확인보다 깔끔합니다.
if amount < 0:
raise ValueError("amount must be positive") # 내장 예외 발생
class InsufficientFundsError(Exception): # 사용자 정의 예외 타입
pass
raise InsufficientFundsError("balance too low")
# ❌ 포괄적인 except는 버그를 숨김 (모든 것을 잡음, 오타/KeyboardInterrupt 포함)
try: ...
except: pass
# ✅ 특정 예외를 잡음; 처리할 수 없는 것은 다시 발생시킴
try: ...
except ValueError as e:
logger.error(e)
raise # 전파하기 위해 다시 발생
✓ 포괄적인 except가 아니라 특정 예외를 잡을 것
✓ 오류를 조용히 삼키지 말 것 (except: pass) — 로깅하거나 처리할 것
✓ 정리에는 finally / 컨텍스트 매니저(with)를 사용할 것
✓ 의미 있고 구체적인 예외 타입을 발생시킬 것
견고한 오류 처리는 안정적인 프로그램에 필수적이며, Python의 접근 방식에는 알아둘 만한 독특한 관용구가 있습니다: try/except/else/finally 구조, EAFP 철학(사전 확인보다 시도하고 처리하는 것, 더 Pythonic하고 경쟁 상태를 피함), 특정 예외를 잡는 것(버그를 숨기는 포괄적 except가 아니라), 그리고 정리에 finally/컨텍스트 매니저를 사용하는 것 등입니다.
이를 이해하면 처리되지 않은 오류로 인한 충돌과, 지나치게 광범위하거나 조용한 예외 처리로 인한 미묘하고 디버깅하기 어려운 문제 — 신뢰할 수 없는 코드의 빈번한 원인 — 를 모두 예방할 수 있습니다.