바이브코더를 위한 파이썬 기초 8편: 오류 메시지는 마지막 줄부터 읽는다
파이썬 오류 메시지(트레이스백)는 마지막 줄부터 읽는다. 자주 보는 오류 6가지, 3.15의 친절해진 메시지, try·except와 AI에게 오류를 전달하는 법을 정리했다.
바이브코딩을 하다 보면 빨간 오류 메시지를 정말 자주 본다. 그 메시지를 읽지 않고 통째로 AI에게 붙여 넣기 쉽다. 그래도 되지만, 마지막 줄 하나만 읽을 줄 알아도 원인을 훨씬 빨리 찾고 AI에게 더 정확히 물어볼 수 있다. 이 글은 '바이브코더를 위한 파이썬 기초' 10편 중 8편으로, 오류 메시지(트레이스백)를 읽는 법과 try / except로 예상 가능한 오류를 처리하는 법을 다룬다. 예제는 Python 3.15 기준으로 설명하며 Python 3.14.2에서 실행해 결과를 확인했다(3.15에서 바뀐 메시지는 공식 문서로 확인했다).
핵심 요약
- 오류는 고장이 아니라 파이썬이 주는 단서다.
- 트레이스백은 맨 아랫줄부터 읽는다. 마지막 줄에 오류 종류와 이유가 있다.
- 그 위의
File "...", line N줄은 오류가 난 파일과 줄 번호를 알려 준다.- 예상할 수 있는 오류만
try / except 오류이름:으로 처리한다.except:로 모든 오류를 숨기면 진짜 원인을 못 찾는다.
오류는 내비게이션의 "이 길은 막혔습니다"다
내비게이션이 "이 길은 막혔습니다"라고 알려 주면 다른 길을 찾을 수 있다. 오류 메시지도 같다. 알려 주기 때문에 고칠 수 있다.
시험지의 채점 표시와도 비슷하지만, 오류 메시지는 그보다 친절하다. 틀린 곳만 표시하는 게 아니라 몇 번째 줄에서 무슨 일이 있었는지까지 알려 준다.
파이썬 오류 메시지(트레이스백) 읽는 순서
숫자가 아닌 글자를 정수로 바꾸려 하면 오류가 난다. 예를 들어 app.py 파일의 3번째 줄에 int("삼")이 있으면 이런 메시지가 나온다(파일 경로는 환경마다 다르다).
Traceback (most recent call last):
File "app.py", line 3, in <module>
number = int("삼")
~~~^^^^^^
ValueError: invalid literal for int() with base 10: '삼'
(~~~^^^^^^ 표시는 그 줄에서 문제가 된 부분을 가리킨다.)
| 위치 | 내용 | 읽는 법 |
|---|---|---|
| 맨 윗줄 | Traceback (most recent call last): | "오류가 났다"는 제목일 뿐이다 |
| 가운데 | File "app.py", line 3 | 어느 파일 몇 번째 줄인지 |
| 그 아래 | number = int("삼") | 문제가 된 코드 |
| 마지막 줄 | ValueError: ... | 오류 종류: 이유. 여기부터 읽는다 |
마지막 줄은 "int()로 바꿀 수 없는 글자 '삼'이 들어왔다"는 뜻이다. 함수 안에서 오류가 나면 가운데 File ... line ... 줄이 여러 개 쌓이는데, 아래로 갈수록 실제로 오류가 난 곳에 가깝다.
자주 보는 오류 종류를 이 시리즈 내용과 함께 정리하면 다음과 같다.
| 오류 | 흔한 원인 | 관련 편 |
|---|---|---|
SyntaxError | 문법이 틀림(괄호·따옴표·콜론 빠짐, =와 == 혼동) | 1·3편 |
NameError | 만든 적 없는 이름, 철자 오타(Print) | 1편 |
TypeError | 종류가 다른 값끼리 계산("20" + 1) | 2편 |
ValueError | 종류는 맞지만 값이 안 맞음(int("삼")) | 이번 편 |
IndexError | 리스트에 없는 번호 | 5편 |
KeyError | 딕셔너리에 없는 키 | 6편 |
Python 3.15에서 더 친절해진 메시지
Python 3.15에서는 없는 기능을 부를 때 맞는 이름을 추천해 주는 메시지가 늘었다. 공식 문서의 예를 보면, 리스트에 push를 쓰면 마지막 부분이 이렇게 나온다(트레이스백 앞부분 생략, Python 3.15 새 기능 문서).
>>> [1, 2, 3].push(4)
AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'?
"Did you mean ...?"이 보이면 그 추천부터 확인해 보자. 이름이 비슷한 후보를 골라 준 것이라 늘 정답은 아니다. push는 자바스크립트 배열에서 쓰는 이름이라, 다른 언어 습관이 섞인 코드에서 이런 메시지를 볼 수 있다.
try / except: 예상할 수 있는 오류 처리하기
사용자가 숫자 대신 글자를 입력하는 일처럼 예상할 수 있는 오류는 미리 처리할 수 있다.
def to_number(text):
try:
return int(text)
except ValueError:
return None
print(to_number("42"))
print(to_number("삼"))
42
None
try 안의 코드를 실행하다가 ValueError가 나면, 그 줄에서 바로 멈추고 except ValueError: 아래로 간다. 오류가 난 줄 다음의 try 코드는 건너뛴다.
흔한 함정: except:로 모든 오류를 삼키면 안전할까
try:
...
except:
pass
이렇게 오류 이름 없이 except:를 쓰고 pass(아무것도 하지 않음)를 두면 프로그램은 멈추지 않는다. 그래서 안전해 보이지만, 오타로 생긴 NameError까지 조용히 숨겨 버린다. 결과가 이상한데 오류 메시지가 하나도 없으니 원인을 찾을 수 없다.
AI 코드에서 except:나 except Exception: pass가 보이면 "어떤 오류를 예상하고 넣은 거야? 그 오류만 처리하도록 바꿔 줘"라고 요청하자. 처리할 오류를 ValueError처럼 이름으로 지정하는 게 원칙이다.
AI에게 오류를 전달하는 법
- 오류 메시지 전체를 붙여 넣는다. 마지막 줄만 잘라 주면 어느 줄에서 났는지를 AI가 모른다.
- 마지막 줄을 먼저 읽고 내가 이해한 원인을 한 줄 덧붙인다. 예: "
int("삼")에서ValueError가 나. 사용자가 글자를 입력한 경우 같아." - 무엇을 하려다 났는지, 어떤 명령으로 실행했는지 적는다.
- 오류 메시지에 들어 있는 API 키, 비밀번호, 개인 폴더 경로는 지우고 보낸다.
스스로 확인하기
- 트레이스백에서 가장 먼저 볼 곳은? → 맨 아랫줄의 오류 종류와 이유. 맨 윗줄은 제목일 뿐이다.
try안의 세 번째 줄에서except가 처리하는 오류가 나면? → 그 줄에서 멈추고 바로except로 간다. 프로그램이 바로 끝나는 건 처리하지 않는 오류일 때다.
직접 해 보기
문자열을 받아 정수로 바꾸되, 실패하면 기본값 0을 돌려주는 to_int(text, default=0)를 만들어 보자. to_int("7")은 7, to_int("abc")는 0이면 성공이다. 막히면 except 뒤의 오류 이름 철자와 들여쓰기를 확인한다.
def to_int(text, default=0):
try:
return int(text)
except ValueError:
return default
print(to_int("7"))
print(to_int("abc"))
7
0
이전 편과 다음 편
- 이전 글: 7편: 함수, print와 return은 다르다
- 다음 글: 9편: 파일 저장과 불러오기에서는 프로그램이 끝나도 남는 파일 저장과, 한글이 깨지지 않게 하는
encoding="utf-8"을 다룬다.
시리즈 전체 목록은 10편 끝에 모아 두었다.