[파이썬]클래스 인스턴스의 고정 속성: __slots__

클래스를 사용해보았다면 __dict__을 통해서 클래스의 인스턴스가 가진 모든 속성을 확인해본적이 있을 것이다. 딕셔너리는 메모리를 많이 잡아먹는 단점이 있는데, 만약 수 백만개의 인스턴스를 생성한다면 그 만큼 사용되는 메모리가 매우 크게 증가한다는 것을 의미한다. 클래스가 가지는 속성을 제한함으로써 최적화를 할 수 있으며 이 때 필요한 __slot__이라는 키워드에 대해서 정리해보자.

__slots__ 이란?

slots은 클래스가 가진 속성을 제한할때 사용한다. 클래스의 __dict__ 속성을 최적화하는 데에 사용할 수 있는데 기존의 딕셔너리로 관리하는 속성을 집합 형태의 Set으로 바꿈으로써 동작한다. 메모리를 절약할 수 있다는 장점이 있다.

코드로 살펴보는 __slots__

slots를 사용하는 클래스와 그렇지 않은 클래스를 정의하고 인스턴스까지 생성한 뒤 각 인스턴스의 네임 스페이스를 살펴보자.

1
2
3
4
5
6
7
8
9
10
11
12
class SlotClass:
__slots__ = ('name', )

class NoSlotClass:
pass

slot = SlotClass()
no_slot = NoSlotClass()
no_slot.name = 'a'

slot.__dict__ # 에러 - slots은 dict을 가지고 있지 않기 때문에
no_slot.__dict__

slot 인스턴스는 slots을 사용하고있기 때문에 더 이상 네임 스페이스를 __dict__을 통해서 관리하지 않는다. 메모리 사용량에 있어서 얼마나 차이가 있는지 실험을 해보자.

slots 사용 여부에 따른 메모리 사용량 비교

1
2
3
4
5
6
7
8
9
10
import timeit

def check_time(obj):
def inner():
obj.name = 'hello'
del obj.name
return inner

min(timeit.repeat(check_time(slot), number=10000000)) # 1.6706519379999918
min(timeit.repeat(check_time(no_slot), number=10000000)) # 2.139917491999995

timeit 모듈의 repeat 함수를 이용했다. 인스턴스의 name 속성에 hello라는 문자열을 저장하는 작업을 천만번 수행하도록 했고 그 중에서 가장 짧은 시간이 출력되도록 했다. 결과는 큰 차이가 발생하진 않았지만 slots를 사용하지 않았을때 시간이 더 걸리는 것으로 보아 작업량이 더 많아 메모리를 더 점유한다고 생각할 수 있겠다.

정리

파이썬 클래스가 가지는 딕셔너리 형태의 속성은 런타임에도 임의의 새로운 속성을 추가할 수 있다는 유연성을 제공해주지만 더 많은 메모리를 사용한다는 단점도 가지고 있다. 클래스 속성을 딕셔너리로 관리하는 대신에 slots을 사용하여 고정된 속성 집합을 사용하게 함으로써 메모리 사용량을 줄이고 최적화 할 수 있다.

정말 많은 객체를 생성할 거라고 예상되는 클래스는 slots으로 속성을 관리하는 것을 추천한다!!


[참고]
패스트캠퍼스 강의

Share