파이썬에서 어떤 클래스 속성이 해당 클래스 안에 직접 정의된 것인지, 아니면 부모 클래스로부터 상속(파생)된 것인지 구분해야 하는 경우가 있습니다. 이럴 때 __dict__ 속성과 hasattr() 함수를 함께 활용하면 간단하게 판별할 수 있습니다.
핵심 원리
클래스.__dict__: 해당 클래스에 직접 정의된 속성만 담고 있는 딕셔너리입니다. 상속받은 속성은 여기에 포함되지 않습니다.hasattr(클래스, '속성명'): 해당 클래스가 속성을 가지고 있는지 확인합니다. 상속받은 속성까지 포함하여 검사하며, 존재하면 True를 반환합니다.
따라서 두 결과를 비교하면 속성이 정의된 것인지 파생된 것인지 알 수 있습니다.
예제 코드
class A:
foo = 1
class B(A):
pass
print(A.__dict__)
# A의 __dict__에 foo가 있으므로, foo는 클래스 A에서 직접 정의된 속성입니다.
print(hasattr(A, 'foo'))
# 클래스 A에 foo 속성이 있으며, 직접 정의된 것입니다.
print(B.__dict__)
# B의 __dict__에는 foo가 없으므로, foo는 클래스 B에서 직접 정의되지 않았습니다.
print(hasattr(B, 'foo'))
# 클래스 B에 foo 속성이 존재하지만, 부모 클래스로부터 상속(파생)된 것입니다.실행 결과
{'__module__': '__main__', 'foo': 1, '__doc__': None}
True
{'__module__': '__main__', '__doc__': None}
True결과 해석
- 클래스 A의
__dict__출력 결과에'foo': 1이 포함되어 있습니다. 즉, foo는 A에서 직접 정의된 속성입니다. - 클래스 B의
__dict__출력 결과에는 foo가 없습니다. 그러나hasattr(B, 'foo')는 True를 반환하는데, 이는 B가 부모 클래스 A로부터 foo를 상속받았기 때문입니다.
참고로 원본 예제는 파이썬 2 스타일의 print 문을 사용했지만, 파이썬 3에서도 위와 같이 print() 함수 형태로 작성하면 동일한 방식으로 동작합니다. 다만 파이썬 3에서는 __dict__에 __qualname__ 같은 추가 항목이 함께 출력될 수 있다는 점을 유의하세요.