Python

[Python - Error] NameError: ... / AttributeError: ... / __getattr__ raise NameError(attr) - 발생 원인 및 체계적인 디버깅 방법

하룻강아지^^ 2022. 4. 13. 21:34
728x90
반응형


요약

- __getattr__ 매서드는 클래스로부터 생성된 인스턴스가 attribute(매서드, 함수, 변수 등)를 찾을 수 없을 경우에 호출됩니다.

- NameError 역시 요청한 attribute가 존재하지 않는 경우에 발생합니다.

- 따라서, 호출하고자 하는 attribute를 아래 표와 같이 살펴봅시다.

- 코드 구조나 완결성과 같이 확인하는데 오래걸리고 복잡한 것 부터 의심하지 말고, 아래 표의 우선순위가 높은 것 부터 (빠르게, 확인하는데 리소스가 적게 드는 것부터) 순서대로 확인해 봅시다.

 

우선
순위
확인 사항 예시
원했던 것 에러 발생
1 오타 여부 np.zeros(5) np.zoros(5)
2 대소문자 구분 np.zeros(5) np.Zeros(5)
3 library의 적절한 import 여부 import numpy as np
print(np.zeros(5))
import numpy as np
print(numpy.zeros(5)) # numpy 모듈을 np로 import 했으므로 NameError 발생
4 library 설치 여부 import numpy as np # numpy 설치 O import numpy as np # numpy 설치 X

 

 


배경

- 파이썬 코딩하면서 가장 많이 접하는 에러 메시지가 NameError: ..., AttributeError: ... 인 것 같습니다.

- 좀 더 잘 짜여진? 복잡한? 코드에서는 __getattr__ raise NameError(attr) ... 인 에러 메시지가 나오기도 합니다.

- 사실 어느 정도 익숙해 지면 자연스럽게 문제가 있는 부분을 찾아내고 고치기도 하지만, 처음에는 생소할 수 있으니 위와 같은 에러 메시지에 어떻게 대처해야 할 지 가이드라인을 제시해 보았습니다.

 

 


설명

- 아래 짧은 코드를 한 줄씩 실행 시켜보면서 확인해 봅시다.

import numpy as np

print(np.zeros(5))     # (정상 작동)       출력 결과       : [0. 0. 0. 0. 0.]
print(np.zoros(5))     # (AttributeError) 확인 우선순위 1 : 오타
print(np.Zeros(5))     # (AttributeError) 확인 운선순위 2 : 대소문자
print(numpy.zeros(5))  # (NameError)      확인 운선순위 3 : import 된 라이브러리의 적절한 호출

 

1. 정상인 경우 : print(np.zeros(5))

- 잘 출력 됩니다.

 

import numpy as np

print(np.zeros(5))     # (정상 작동)       출력 결과       : [0. 0. 0. 0. 0.]

 

 

 

2. 오타가 있는 경우 : print(np.zoros(5))

- zeros 가 아니라 zoros 로 잘못 입력 했네요. numpy 모듈은 zoros라는 매소드를 가지고 있지 않기 때문에 attributeError를 띄웁니다.

 

import numpy as np

print(np.zoros(5))     # (AttributeError) 확인 우선순위 1 : 오타

 

 

3. 대소문자가 잘 못 되었을 때 : print(np.Zeros(5))

- 오타의 한 종류라고 생각하면 2번과 같습니다. attributeError를 띄웁니다.

 

import numpy as np

print(np.Zeros(5))     # (AttributeError) 확인 운선순위 2 : 대소문자

 

 

4. 모듈 이름이 잘못 되었을 때 : import numpy as np

- 모듈 이름에 오타가 있을 경우도 당연히 문제가 되지만, 아래와 같은 경우도 살펴봅시다.

- numpy 모듈을 np 라는 별칭으로 임포트 하였습니다. 그렇다면 실제 사용을 할 때에도, numpy 모듈을 사용하려면 np로 사용을 해야합니다.

- 그렇지 않으면 NameError를 띄우게 됩니다.

- 즉, 어떤 모듈을 np 와 같은 별칭으로 임포트 하였을 때, 혹시 모듈의 원래 이름 (여기서는 numpy) 으로 호출을 시도하지는 않았는지 확인해 봅니다.

 

import numpy as np

print(numpy.zeros(5))  # (NameError)      확인 운선순위 3 : import 된 라이브러리의 적절한 호출

 

 

 


참고: __getattr__ 란?

- 자세한 설명은 [Python - Tip] __getattr__ 과 __getattribute__ 의 차이 및 활용 예시 를 참고해 주세요.

- 간단하게 설명하면, __getattr__은 인스턴스가 코드에서 요청한 attribute (변수 등)를 찾지 못했을 경우, 가장 마지막에 호출하는 매소드입니다.

- 즉, 컴퓨터가 사용자가 요청한 예를 들면 "notDefinedVar" 이라는 변수를 여기저기 찾아봤는데도 찾을 수 없을 때, __getattr__ 매소드를 호출하게 됩니다.

- 따라서, __getattr__이 호출된경우, 특별한 경우가 아니면 "존재하지도 혹은 정의되지도 않은 변수를 호출했구나", "오타가 있었나 보구나" 정도로 생각을 하면 될 것 같습니다.

 

 

728x90
반응형