파이썬 __getattr__ 와 __getattribute__ 의 차이

Photo by Nigel Tadyanehondo on Unsplash

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:    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를 찾을 수 없을경우) 가장 “후순위”로 호출된다고 이해할 수 있다.

Happy coding, enjoy learning :)

Happy coding, enjoy learning :)