
try-except를 더 명확하게 쓰는 방법
파이썬 개발자라면 try-except 구문을 자주 사용한다. 예외 처리는 필수다. 하지만 좋은 코드는 단순히 동작하는 코드가 아니라, 의도가 분명하게 보이는 코드다. 현실에서는 try 블록 안에 많은 코드를 한꺼번에 넣는 경우가 많다. “일단 여기 넣어두면 예외는 잡히겠지”라는 생각 때문이다. 이렇게 되면 성공 경로와 실패 경로가 섞여 코드의 의도가 흐려진다.
이 문제를 해결하는 간단하면서도 강력한 방법이 있다. 바로 try-except-else 구조다.
1. else는 “나머지”가 아니라 “성공 경로”다
많은 사람이 try 구문의 else를 if문의 else처럼 이해한다. 하지만 의미는 전혀 다르다.
try의 else는 try 블록에서 예외가 하나도 발생하지 않았을 때만 실행된다.
- 특정 예외가 아닐 때 실행되는 것이 아니다.
- 완전히 성공했을 때만 실행된다.
finally와도 구분해야 한다.
- finally: 성공 여부와 상관없이 항상 실행
- else: 성공했을 때만 실행
간단한 예제
user_input = "123" # 또는 "abc"
try:
value = int(user_input)
except ValueError:
print("잘못된 숫자 형식입니다.")
else:
print(f"성공적으로 변환했습니다. 입력 값: {value}")
동작은 명확하다.
- "abc" → ValueError 발생 → except 실행 → else 실행 안 됨
- "123" → 예외 없음 → except 건너뜀 → else 실행
else를 사용하면 성공했을 때만 실행되어야 하는 코드를 구조적으로 분리할 수 있다.
2. try 블록은 최대한 작게 유지해야 한다
좋은 예외 처리의 핵심 원칙은 하나다.
예외가 발생할 수 있는 코드만 try로 감싼다.
나쁜 예: try 블록이 너무 넓다
try:
user = get_user(user_id)
email = user["email"]
send_email(email)
except KeyError:
log_error("이메일 키가 없습니다.")
이 코드에서 KeyError가 발생하면 원인을 바로 알기 어렵다.
- user["email"]일 수도 있고
- send_email() 내부의 다른 코드일 수도 있다
try 블록이 넓을수록 디버깅은 어려워진다.
개선된 예: 실패 지점을 한 줄로 제한
user = get_user(user_id)
try:
email = user["email"]
except KeyError:
log_error("이메일 키가 없습니다.")
return
else:
send_email(email)
이제 KeyError가 발생할 수 있는 위치는 명확하다.
또한 except에서 바로 return 하여 잘못된 상태로 코드가 진행되는 것을 막는다.
이 구조는 가드 절(guard clause) 역할도 한다.
3. 성공 로직과 실패 로직을 분리하라
아래 패턴은 흔하지만 의도가 흐릿하다.
try:
value = int(user_input)
print(value)
do_something(value)
except ValueError:
print("잘못된 숫자 형식입니다.")
이 try 블록에는 두 가지 책임이 섞여 있다.
- 예외가 발생할 수 있는 작업
- 성공 후 처리 로직
이는 소프트웨어 설계의 기본 원칙인 **관심사 분리(Separation of Concerns)**에 어긋난다.
의도가 드러나는 구조
try:
value = int(user_input)
except ValueError:
print("잘못된 숫자 형식입니다.")
else:
print(value)
do_something(value)
이 구조를 보면 바로 이해된다.
- 변환은 실패할 수 있다
- 실패하면 except
- 성공하면 else만 실행된다
else 블록은 완전히 성공했다는 전제 위에서 동작하는 안전한 영역이다.
4. 모든 예외를 잡으려 하지 마라
다음 코드는 대표적인 안티패턴이다.
except Exception:
pass
이 코드는 모든 오류를 조용히 숨긴다.
- 버그는 남고
- 로그는 없고
- 원인은 알 수 없다
올바른 원칙
1. 예상 가능한 실패만 잡는다
- 사용자 입력 오류
- 파일 없음
- 형식 오류
2. 프로그래밍 오류는 그대로 실패하게 둔다
- TypeError
- 논리 오류
- 잘못된 가정
프로그램이 멈추는 것이, 잘못된 상태로 계속 실행되는 것보다 낫다.
5. finally와 else를 한눈에 비교하기
| 블록 | 실행 조건 | 주 용도 |
| try | 항상 실행 | 예외 가능 코드 |
| except | 예외 발생 시 | 실패 처리 |
| else | 예외 없음 | 성공 후 로직 |
| finally | 항상 실행 | 자원 정리 |
마무리: 의도를 구조로 표현하라
try-except-else의 가치는 단순히 예외를 처리하는 데 있지 않다.
의도를 코드 구조로 드러내는 데 있다.
- try: 실패할 수 있는 작업
- except: 실패 처리
- else: 성공 후 처리
이 원칙을 지키면 코드는 더 읽기 쉬워지고, 디버깅과 유지보수가 쉬워진다. 이것이 경험 많은 파이썬 개발자의 코드다.
'잡(job)기술 > 파이썬 공부' 카테고리의 다른 글
| 나의 파이썬 코드를 한 단계 끌어올릴 5가지 설계 원칙 (1) | 2026.01.14 |
|---|---|
| 내 코드가 외부 API와 통신한 척하게 만드는 방법 - 파이썬 Mocking 핵심 개념 2가지 (3) | 2026.01.02 |
| 당신의 테스트는 안녕한가요? Pytest로 데이터베이스를 제대로 검증하는 3가지 핵심 원리 (0) | 2026.01.02 |
| 파이썬 sqlite3, 혹시 이렇게 쓰고 있는가? - 나의 코드를 바꿔놓을 4가지 핵심 팁 (0) | 2025.12.31 |
| Poetry로 Python 프로젝트 환경 만들기 (2) | 2025.06.24 |