본문 바로가기
Programming/Python

[Python] 에러 error / 오류 메세지 해석하기 / 에러 코드 종류 / 예외처리 try, except

by EunjiBest 2022. 5. 24.

[Python] 에러 error / 오류 메세지 해석하기 / 에러 코드 종류 / 예외처리 try, except

 

 

 

에러 error

 

코딩을 하다보면 크고 작은이유로 반드시 나타나는 에러!

(제발 한 번이라도 오류없이 넘어가주세요ㅠㅠ)

 

눈물나는 에러의 현장...

 

영어로 장황하게 써있는 탓에 다가가기 무서운 비주얼을 가지고 있다.

하지만 이 에러메세지는 생각보다? 친절한 편이고, 오류를 찾는데에 큰 도움이된다.

 

그래서 포스팅하는 '에러를 읽는 법을 알아보자!'

 

에러메세지는 코딩 툴에따라서 조금씩 다르게 나타나지만,

큰 틀은 비슷하고, 들어있는 내용도 똑같다.

 

나는 구글코랩(Google Colab)을 사용해서 에러분석을 해보도록 하겠다!

개인적으로 코랩의 에러 메세지는 매우 친절하고, 상세하며, 읽기 쉽게 형형색색으로 구분되어있고, UI도 명확하다고 생각한다.

 

 

 

 

 

에러 메세지 읽기

 

간단하게 에러의 틀을 알아보자.

 

def hi(name):
  print("Hi," + nam)

hi("eunji")

 

다음과 같이 잘못된 코드를 입력해보았다.

hi함수 안 출력값 name에 오타가있다.

 

당연히 오류메세지가 뜰 것이고

다음과 같다.

 

① NameError

② Traceback (most recent call last)

③ <ipython-input-3-348d637380ab> in <module>()
          2 print("Hi," + nam)
          3
----> 4 hi("eunji")

④ <ipython-input-3-348d637380ab> in hi(name)
          1 def hi(name):
----> 2 print("Hi," + nam)
          3
          4 hi("eunji") 

⑤ NameError: name 'nam' is not defined

 

하나씩 뜯어보자.

 

NameError : 이름 에러 (에러의 종류)

 

Traceback : 뒤에서부터 온다는 뜻이다.

most recent call last :가장 최근에 부른 call이 가장 마지막에 온다는 뜻이다.

그래서 에러를 읽을 때 가장 마지막 call 부분부터 거꾸로 올라오면서 읽어라!고 말해주는 코드이다.

 

에러메세지 자체가 마지막 줄부터 설명이 되어있다.

 

 

<ipython-input-3-348d637380ab> : 현재 작업하고 있는 파이썬 파일 이름이나 경로 등..

<module> : 함수내부가 아닌 외부에서 실행된 코드를 의미

----> 4 hi("eunji") : 이 코드를 부르고 있는 시점부터, 에러가 시작된 것.

 

 

3번에서의 오류가 왜 일어났을까?

<ipython-input-3-348d637380ab> : 3번과 같은 파일이나 경로 등..에서 일어난 오류이다.

in hi(name) : hi(name)이라는 함수 안에서 오류가 발생했다.

----> 2 print("Hi," + nam) : 이 코드에서 오류가 발생되었다.

 

즉, 4번에서 결정적인 에러가 발생한 것을 알 수 있는 것을 보아,

맨 마지막 줄이 진짜 오류를 발생시킨 부분이고,

그 위에있는 줄은 에러가 발생되는 경로이다.

 

 

⑤ 에러코드이다.

NameError: 이름 에러라는 에러의 종류

name 'nam' is not defined : 'nam'이라는 변수가 정의되지 않았다. (찾을 수 없다.)

 

내가 정의하지 않은 변수이니 오타나, 변수를 정의하지 않았는지 등을 확인해볼 여지가 생겼다.

 

 

간단하게나마

에러메세지를 읽어보았다. 

대부분 구성은 이렇게 되어있고,

마지막 부분에 진짜 오류를 발생시킨 부분과 에러에 대한 설명이 나와있다.

그 윗부분은 프로그래밍이 길어질 수록 복잡해지지만,

오류가 발생되는 경로이기 때문에 정말 알 수 없는 오류가 생겼을 때 도움이 되기 때문에 알아둘 필요가있다.

 

 

 

 

 

 

에러코드

 

1. Syntax error 

 

잘못된 문법이라는 뜻이다. 때문에, 초보자들이 엄청 많이 내는 오류 중 하나일 듯싶다.

 

def hi(name)
  print("Hi," + name)

hi("eunji")

 

함수 정의 마지막에 : 콜론을 빼보았다.

 

File
"<ipython-input-4-7a02a21bc917>", line1
def hi(name)
^
SyntaxError:invalid syntax

 

<ipython-input-4-7a02a21bc917> 파일에서, 

line 1 첫 번째 줄 def hi(name)에서 오류가 생겼다.

 

SyntaxError : 잘못된 문법

invalid syntax : 컴퓨터가 이해할 수 없는 코드이다.

 

라고 쉽게 해석이 가능하다.

 

첫번째 에러메세지와 다르게 Traceback (most recent call last)가 없다.

왜냐하면,

파이썬의 문법이 맞다면 어디서부터 틀린지 등을 말해줄 수 있지만,

파이썬 문법 자체가 아니기 때문에 컴퓨터가 이해할 수 조차 없기 때문이다.

 

 

 

2. Name error

 

내 기준 하루에 몇백번씩 보는 에러코드인 것같다.

성격이 급해서 한국어 오타도 많이내는 편인데,

영어로 타자를 치다보니 알게모르게 갖가지의 오타들이 많이 생긴다.

몇백줄이 넘어가는 파일에서 내 오타를 찾기 어려울 때 한 줄기의 빛같은 존재이다.

 

위에서 네임에러로 예시를 들었으니 간단하게만 설명하자면,

정의한 적 없는 변수에 접근하려고 할 때 나타나는 오류이다.

실제로 변수 정의를 하지 않아서 생길 때도 있지만, 대부분 오타로 인해 생기는 경우가 많다.

 

 

3. Type error

 

def add_num(number):
  result = 0
  for n in number:
    result += number
  return result

add_num(['a','b','c'])

 

간단하게 리스트에 있는 숫자를 더하는 함수를 만들어보았다.

하지만 리스트에는 숫자가 아닌, 문자열이 들어가있다.

 

그럼 어떤 오류를 낼까?

 

TypeError Traceback (most recent call last)
<ipython-input-8-1dd9a61434a9> in <module>()
          5 return result
          6
----> 7 add_num(['a','b','c'])

<ipython-input-8-1dd9a61434a9> in add_num(number)
          2 result = 0
          3 for n in number:
----> 4 result += number
          5 return result
          6

TypeError: unsupported operand type(s) for +=: 'int' and 'str'

 

이것은 예외상황 때문에 발생한 것이다. 따로 예외처리를 하지 않아서 오류가 난 것인데

사용자가 숫자가 아닌 문자를 입력할 것이라는 생각을 하지 않은 것이다.

 

unsupported operand type(s) for += : +=는 지원하지 않는 연산자이다.

왜 지원하지 않을까? 'int' and 'str' 이기 때문에.

 

위 함수에서 result 는 int이고, n은 str이다.

int와 str은 type이 다르기 때문에 연산이 되지않는다.

 

TypeError는 서로 다른 데이터형으로 계산을 하려했을 때 생기는 것이다.

때문에, 두가지 타입을 어떻게 통일할것인지? 사용자가 문자열을 집어넣었을 때 어떻게 해줄 것인지?를 생각하여 에러발생을 막을 수 있다.

 

 

 

 

4. Import error

 

딱히 배우지 않더라도 import가 잘못되었을 때 생기는 오류처럼 보인다.

 

from numpy import zero

print(zero(10))

 

zero배열을 10개 만들기 위해서 numpy를 불러보았다.

numpy를 불러올 때 메서드 이름을 zeros가 아닌 zero로 잘못입력해보자.

 

그럼 어떤 오류가 뜰까?

 

ImportError Traceback (most recent call last)
<ipython-input-10-d8925a2ca0b6> in <module>()
----> 1 from numpy import zero
        2
        3 print(zero(10))
ImportError: cannot import name 'zero' from 'numpy'

 

마지막 줄을 보면 ImportError가 뜨면서

zero라는 이름을 찾을 수 없다고 친절하게 설명을 해준다.

 

당연하게도 내가 사용하고자는 클래스나, 메소드의 이름을 정확하게 알고있는지 확인해보면

이런 오류는 손쉽게 해결할 수 있다.

 

 

 

 

 

 

 

try / except

 

 

여기까지, 자주쓰이는 오류에 대해서 알아봤다.

솔직히 영어로 쓰여있어서 어려워보이는 것이지,

따로 배우지 않아도 영문해석을 잘 할 수 있다면 오류메세지가 무엇을 의미하는지는 대충 알 수 있다.

(번역기 쓰면 된다. 정말 프로그래밍은 영어와 뗼 수 없는 사이이다ㅠ)

 

그럼 오류코드를 읽는 것보다 중요한 것은!

무엇일까?

바로 오류를 만들지 않는 것이다. 오류를 예측하는 능력!

 

오류를 예측하는 능력은 개발자의 능력이기 때문에 프로그래밍으로 해결할 수 없고,

예측이 된다면, 예외처리는 프로그래밍으로 할 수 있다.

 

 

try - except 문법이 있다.

 

try:
   시도할 것
expect 예측한 오류:
   오류가 난다면 이렇게 해라

 

try에서 시도하는 문장이 정상으로 돌아갈 수도 있고 에러가 날 수도 있다.

에러가 날 것을 대비해서 expect를 써주고

이러한 식으로 처리를 해라!라고 리턴해준다.

 

하.. 내가 쓰고도 무슨말인지 모르겠다.

다음 예문을 보자.

 

def average(numbers):
  try:
    return sum(numbers) / len(numbers)
  except ZeroDivisionError:
    print("분모가 0이다")

 

평균을 구하는 함수이다.

try의 return값에 총합 / 길이를 넣어 평균을 구하려고한다.

이때, 길이(분모)가 0인 예외상황으로 인해 ZeroDivisionError가 날 것을 미리 예측했다면,

expect문에  ZeroDivisionError를 적어주고, 분모가 0이다!라고 사용자에게 알려주는 메세지를 출력하여

오류를 막는 것이다.

 

 

 

 

 

 

 

 


사실 따로 외우거나 공부를 하지 않아도

많은 오류를 내보면, 대충 이런뜻이구나, 여기서 오류가 났겠구나라는게

눈에 바로바로 보이기 시작한다.

(실제로 내눈에는 죽어도 안보이는 오류들을 선배들이 슬쩍 지나가면서 보다가 '야!이거잖아'라고 말하는 경우가 엄청 많다)

 

하지만 엄청나게 긴 코드를 짰을때,

오류가 있다면...? 에러메세지 없이는 해결하기 힘들 것이다.

그리고 가장 중요한 것은

버그가 발생하지 않게 하는 것, 오류를 예측하고 그에대한 처리를 해주는 것이 중요하다!

 

관련 게시글보기

↓↓↓↓↓↓↓

 

https://eunjibest.tistory.com/115

 

사용자 경험에서의 디버깅의 중요성 : 프로그래밍 버그(Bug) / 예외(Exception) / 예외처리(Exception Hand

사용자 경험에서의 디버깅의 중요성 : 프로그래밍 버그(Bug) / 예외(Exception) / 예외처리(Exception Handling) 버그(Bug)와 예외(Exception) - 버그 컴퓨터 프로그래밍에서 버그란? 코드가 원하는대..

eunjibest.tistory.com

 

반응형

댓글