Post

[Py: Class] 7.__slots__


__dict__의 단점

  • 앞서 이야기했듯이 기본적으로 Python의 모든 객체는 __dict__라는 딕셔너리를 가지고 있어서 객체의 속성을 저장한다. __dict__는 유연성을 제공하지만, 메모리를 상당히 많이 사용한다.


  • 하지만, 아래와 같은 3차원 좌표 객체를 이용해 특정 물체를 상세히 모델링한다고 가정했을 때, 수백 개에서 수천 개가 넘는 객체가 생성되는 동시에, 딕셔너리가 차지하는 메모리 사이즈도 기하급수적 증가하여 메모리 오버헤드 문제가 발생될 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
      class point3d:
          def __init__(self, x, y, z):
              self.x = x
              self.y = y
              self.z = z
          def __str__(self):
              return '({0}, {1}, {2})'.format(self.x, self.y, self.z)
        
      def main():
          p1 = point3d(1, 1, 1)
          p2 = point3d(2, 2, 2)
          print(p1)
          print(p2)
        
      main()
    



__slots__ 이란?

  • 위와 같은 문제 상황에서 __slots__를 사용하면 메모리 사용량이 큰 __dict__를 생성하지 않고, 지정된 객체를 저장하기위한 고정된 메모리를 할당하 메모리 오버헤드 문제를 예방할 수 있다.
    • 장점: 많은 수의 객체를 생성할 때 1) 메모리 효율성을 증가시키는 동시에, 값 탐색을 위해 해시 변환이 필요한 딕셔너리와 달리 속성의 위치를 미리 정의하여 고정시키기 때문에 2) 연산속도를 높일 수(약 20% 향상) 있다.
    • 단점: 딕셔너리의 외부 접근을 통한 객체의 추가 삭제에 대한 유연성은 사라진다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
     class point3d: 
         __slots__ = ('x', 'y', 'z') # 변수를 x, y, z로 제한한다.
        
         def __init__(self, x, y, z):
             self.x = x
             self.y = y
             self.z = z
       
         def __str__(self):
             return '({0}, {1}, {2})'.format(self.x, self.y, self.z)
        
     def main():
         p1 = point3d(1, 1, 1)
         p2 = point3d(2, 2, 2)
         print(p1)
         print(p2)
        
     main()
    


  • 따라서 __slots__의 사용은 다음의 상황에서 적절하다.
    • 메모리 최적화가 필요한 경우
    • 데이터 무결성을 유지하기 위해 속성의 동적 추가를 원하지 않는 경우



References

  • 윤성우, 『윤성우의 열혈 파이썬 중급편』, ORANGE MEDIA(2021)
This post is licensed under CC BY 4.0 by the author.