파이썬 __getattr__ 와 __getattribute__ 의 차이
Python에서 __getattr__
, __getattribute__
의 차이점, 그리고 추가로 getattr()
를 간단히 알아보자.
__getattr__
__getattr__
는 인스턴스에 해당 attribute가 없을경우 호출된다.
즉, 다 찾아봐도 없으면 __getattr__
를 호출하게된다(인풋인자로 해당 attribute를 넘겨주면서).
쉽게말해 제일 “후순위”로 호출되는 녀석이라 볼 수 있다.
__getattribute__
__getattribute__
는 인스턴스에 해당 attribute가 있든지 없든지 호출되는데,
제일 “선순위”로 호출되는 녀석이다.
즉, 인스턴스에 그 attribute가 있어도, __getattribute__
를 먼저 호출하면서 인풋인자로 해당 attribute를 넘겨주게 된다.
getattr()
예시를 보기 전에, 그럼 getattr()는 무엇인지 체크 후 넘어가자.
getattr()
는 2개 또는 3개의 인풋인자를 받는다.
getattr(myObj, ‘myAttribute’)
라고 하면, 이것은 myObj.myAttribute
와 동일하다(이때 getattr의 두번째인자는 string타입).
getattr(myObj, ‘anotherAttribute’, ‘myDefault’)
라고 하면, 3번째 인자는 디폴트값이 된다. 즉, 2번째인자로 넣어준 attribute가 없을경우 3번째 인자가 리턴된다.
예제 코드
그럼 __getattr__
와 __getattribute__
의 예시를 보자.
class A: def __getattr__(self, name): return (‘hahaha-’+name)
a = A()a.ace = ‘ace value’
print(a.ace)print(a.ace2)print(a.__dict__)
결과는 다음과 같다.
ace valuehahaha-ace2{‘ace’: ‘ace value’}
- ace라는 녀석은 존재하니까 그 값 그대로 출력했으나,
- ace2라는 녀석은 찾을 수 없었기 때문에
__getattr__
를 호출했다는 것을 확인할 수 있다. a.__dict__
를 출력해보면 ace라는 attribute와 그 값을 볼 수 있다.
이때 class A에 __getattribute__
를 추가한다면 어떻게 될까?
class A: def __getattr__(self, name): return (‘hahaha-’+name) def __getattribute__(self,name): return (‘jajaja-’+name)
a = A()a.ace = ‘ace value’
print(a.ace)print(a.ace2)print(a.__dict__)
결과는 다음과 같다.
jajaja-acejajaja-ace2jajaja-__dict__
- ace에는 ‘ace value’라는 값을 할당해줬음에도 불구하고
__getattribute__
가 호출되어 “먼저 가로챈다”는 것을 알 수 있다. - ace2는 존재하지 않는 녀석인데, 이때도
__getattr__
가 아닌__getattribute__
가 호출된다. a.__dict__
의 출력결과를 보면,__getattribute__
가 그야말로 가장 “선순위”로 호출된다는것을 알 수 있다.
요약하면,
__getattribute__
는 (해당 attribute가 있든 없든) 가장 “선순위”로 호출되고,__getattr__
는 (해당 attribute를 찾을 수 없을경우) 가장 “후순위”로 호출된다고 이해할 수 있다.