요약
- __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__이 호출된경우, 특별한 경우가 아니면 "존재하지도 혹은 정의되지도 않은 변수를 호출했구나", "오타가 있었나 보구나" 정도로 생각을 하면 될 것 같습니다.