부록. 자주 만나는 오류
하리가 알려 주는 오류 메시지가 무슨 뜻인지, 어떻게 고치는지 모아 봤어요.
오류는 “틀렸다”는 딱지가 아니라 어디가 왜 안 되는지 알려 주는 안내예요. 하리는 조용히 넘어가는 대신 이유를 말해 줘요. 오류가 나면 이렇게 나와요.
런타임 오류: 종류: 설명
앞의 종류(TypeError, ReferenceError …)가 오류의 이름이고, 뒤가 무슨 일인지 풀어 쓴 문장이에요. 아래에서 오류를 하나씩 일부러 내 보면서, 원인과 고치는 법을 알아봐요. (오류를 일단 해보자로 잡는 법은 9장에 있어요.)
변수를 못 찾을 때
만든 적 없는 변수를 쓰거나, 이름을 잘못 썼어요.
틀"{'없음'}"을 출력하자
ReferenceError: ‘없음’ 변수를 찾을 수 없어요.
고치려면: 이름이 맞는지 확인하고, 쓰기 전에 정하자로 먼저 만들어 두세요. 반복문이나 오류 처리 안에서 처음 만든 변수는 그 밖에서 쓸 수 없어요.
없는 함수를 부를 때
없는 함수를 불렀어요. 이름 오타이거나 함수를 만들기 전에 불렀을 수 있어요.
<없는함수>()를 실행하자
MethodNotFoundError: ‘없는함수’ 함수를 찾을 수 없어요.
고치려면: 함수 이름을 확인하고, 다른 파일이나 모듈의 함수라면 가져오자로 먼저 가져오세요.
타입이 다른 값을 담을 때
[숫자]로 정한 변수에 글자를 넣는 것처럼, 정해 둔 타입과 다른 값을 담으려 했어요.
'나이'를 [숫자]인 "스물"로 정하자
TypeError: ’나이’에는 ‘숫자’ 타입만 담을 수 있어요. ‘문자열’ 값이 들어왔어요.
고치려면: 값의 타입을 맞추거나, 변수를 만들 때 타입을 다시 정하세요. 타입을 정하지 않은 변수는 무엇이든 담을 수 있어요.
숫자와 글자를 더할 때
숫자와 글자처럼 서로 다른 타입을 그냥 더하려 했어요. 하리는 마음대로 바꿔서 계산하지 않아요.
(10 + "안녕")을 출력하자
TypeError: ‘+’ 연산은 ’숫자’와(과) ‘문자열’ 사이에서 할 수 없어요. 자동 형변환은 하지 않아요.
고치려면: <숫자로>()나 <문자로>()로 타입을 직접 바꾸세요.
0으로 나눌 때
어떤 수를 0으로 나눴어요.
(10 / 0)을 출력하자
DivideByZeroError: 0으로 나눌 수 없어요.
고치려면: 나누기 전에 나누는 수가 0이 아닌지 만약으로 확인하세요.
목록 범위를 벗어날 때
목록의 길이보다 큰 번째를 달라고 했어요. 번째는 1부터 세요.
'과일'을 [(문자열)목록]인 ["사과"]로 정하자
'과일'의 5번째 값을 출력하자
IndexOutOfBoundsError: 목록의 길이를 벗어난 위치(인덱스)예요.
고치려면: '목록'의 '길이'로 길이를 확인하고 그 안의 번째만 쓰세요. 비어 있는 목록에서 꺼낼 때도 같은 오류가 나요.
사전에 없는 이름을 찾을 때
사전에 없는 이름(키)을 찾았어요.
'정보'를 [(문자열, 문자열)사전]인 {"이름": "하나"}로 정하자
'정보'의 "직업"을 출력하자
KeyError: 사전에서 ‘직업’ 이름을 찾을 수 없어요.
고치려면: 이름이 맞는지 확인하세요. 사전에 이름을 먼저 넣어 두어야 꺼낼 수 있어요.
고정한 값을 바꿀 때
고정하자로 만든 값을 바꾸려 했어요.
'상수'를 [숫자]인 3으로 고정하자
'상수'를 5로 정하자
ConstantAssignmentError: 상수 ’상수’의 값은 변경할 수 없어요.
고치려면: 바뀌어야 하는 값이라면 정하자로 만드세요.
인자가 모자랄 때
함수가 필요로 하는 인자를 주지 않았어요.
<두배>를 만들자 ([숫자]인 '수'):
('수' * 2)를 돌려주자
<두배>()를 출력하자
MissingArgumentError: ‘수’ 인자가 필요해요.
고치려면: 함수를 만들 때 정한 인자를 모두 주세요. 인자에 기본값(= 값)을 정해 두면 생략해도 돼요.
인자가 너무 많을 때
함수가 받는 것보다 많은 인자를 줬어요.
<두배>를 만들자 ([숫자]인 '수'):
('수' * 2)를 돌려주자
<두배>(1, 2)를 출력하자
ArgumentError: 인자가 너무 많아요. 1개를 기대했는데 2개를 받았어요.
고치려면: 함수의 인자 개수에 맞춰서 주세요.
돌려준 값의 타입이 다를 때
[숫자]를 돌려주는처럼 돌려줄 타입을 적었는데 다른 타입의 값을 돌려줬어요.
[숫자]를 돌려주는 <나이>를 만들자 ():
"스물"을 돌려주자
<나이>()를 출력하자
TypeError: ‘나이’ 함수는 ‘숫자’ 타입을 돌려줘야 하는데 ‘문자열’ 값을 돌려줬어요.
고치려면: 돌려주는 값을 고치거나, 돌려주는 타입을 고치거나 지우세요.
숨긴 속성을 밖에서 부를 때
숨기자로 만든 속성이나 함수를 클래스 밖에서 불렀어요.
[노트]를 설계하자:
'일기'를 [문자열]인 "비밀"로 정하여 숨기자
'노트'를 [노트]인 새로운 [노트]()로 정하자
'노트'의 '일기'를 출력하자
AccessViolationError: ‘일기’ 속성은 내부 전용(private)이라 외부에서 부를 수 없어요.
고치려면: 클래스 안의 함수를 통해서 다루거나, 밖에서 써야 하는 것이라면 숨기지 마세요.
숫자로 바꿀 수 없을 때
숫자로 바꿀 수 없는 글자를 <숫자로>()에 줬어요.
<숫자로>("가나다")를 출력하자
ConversionError: ’가나다’을(를) 숫자로 바꿀 수 없어요.
고치려면: 글자가 숫자 모양("12", "3.5")인지 확인하세요. 사용자에게 입력받은 값이라면 일단 해보자로 감싸는 것도 좋아요.
비어있음의 속성을 찾을 때
비어있음인 값의 속성이나 함수를 찾았어요.
'값'을 비어있음으로 정하자
'값'의 '이름'을 출력하자
MemberAccessError: ‘null’ 타입의 값에는 멤버로 접근할 수 없어요.
고치려면: 값이 비어 있지 않은지 ('값'과 비어있음이 다르다)로 먼저 확인하세요. 준비하자로만 만든 변수는 값을 넣기 전까지 비어 있어요.
글자를 고치려 할 때
글자의 몇 번째 글자를 바꾸려 했어요. 글자는 만들어진 뒤에는 바꿀 수 없어요.
'이름'을 [문자열]인 "하나"로 정하자
'이름'의 1번째를 "김"으로 정하자
ImmutableAssignmentError: 문자열은 바꿀 수 없는 값이라서 몇 번째 글자를 다시 정할 수 없어요.
고치려면: 새 글자를 정하자로 다시 만들어 담으세요.
조건이 참·거짓이 아닐 때
만약이나 동안 반복의 조건에 숫자나 글자를 그대로 썼어요. 참이나 거짓만 쓸 수 있어요.
'나이'를 [숫자]인 20으로 정하자
만약 ('나이') 라면:
"성인"을 출력하자
TypeError: 숫자 값은 조건으로 쓸 수 없어요. 조건에는 참이나 거짓이 와야 해요.
고치려면: ('나이' >= 20)처럼 비교로 분명하게 쓰세요.
호출이 너무 깊을 때
함수가 자기 자신을 끝없이 불러서 호출이 10000단계를 넘었어요.
<무한>을 만들자 ('n'):
<무한>('n' + 1)를 실행하자
<무한>(1)를 실행하자
RecursionError: 호출이 너무 깊게 쌓여서 10000단계를 넘었어요.
고치려면: 재귀 함수에는 언제 멈출지(만약으로 끝내는 경우)를 꼭 넣으세요.
없는 모듈이나 도구를 가져올 때
없는 모듈을 가져오려 했어요.
[없는모듈]에서 <도구>를 가져오자
ImportError: 패키지 ’[없는모듈]’를 찾을 수 없어요.
고치려면: 모듈 이름과 도구 이름을 확인하세요. 표준 라이브러리는 10장에 있어요.