파이썬 __ slots __
클래스를 사용해보았다면 __dict__을 통해서 클래스의 인스턴스가 가진 모든 속성을 확인해본적이 있을 것이다. 딕셔너리는 메모리를 많이 잡아먹는 단점이 있는데, 만약 수 백만개의 인스턴스를 생성한다면 그 만큼 사용되는 메모리가 매우 크게 증가한다는 것을 의미한다. 클래스가 가지는 속성을 제한함으로써 최적화를 할 수 있으며 이 때 필요한 __slot__이라는 키워드에 대해서 정리해보자.
slots 이란?
slots은 클래스가 가진 속성을 제한할때 사용한다. 클래스의 dict 속성을 최적화하는 데에 사용할 수 있는데 기존의 딕셔너리로 관리하는 속성을 집합 형태의 Set으로 바꿈으로써 동작한다. 메모리를 절약할 수 있다는 장점이 있다.
( __slots__은 객체마다 생성되는 __dict__을 생성못하게 하여 메모리 효율성을 높이고, 객체의 속성(변수) 추가(생성)을 제한할 수 있다. )
코드로 살펴보는 slots
slots를 사용하는 클래스와 그렇지 않은 클래스를 정의하고 인스턴스까지 생성한 뒤 각 인스턴스의 네임 스페이스를 살펴보자.
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__을 통해서 관리하지 않는다. 메모리 사용량에 있어서 얼마나 차이가 있는지 실험을 해보자.
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 '3D 좌표 : ({0}, {1}, {2})'.format(self.x, self.y, self.z)
def main():
p1 = Point3D(1, 1, 1)
p2 = Point3D(24, 27, 31)
print(p1) # 3D 좌표 : (1, 1, 1)
print(p2) # # 3D 좌표 : (24, 27, 31)
#p1.v1 = 30
# AttributeError: 'Point3D' object has no attribute 'v1'
#print(p1.__dict__)
# AttributeError: 'Point3D' object has no attribute '__dict__'
main()
- 클래스 내에 slots 가 없으면
- p1.v1 = 30 이 실행되어
- print(p1.dict)의 결과, {'x': 1, 'y': 1, 'z': 1, 'v1': 30} 출력됨
slots 사용 여부에 따른 메모리 사용량 비교
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으로 속성을 관리하는 것을 추천한다!!
'Engineering WIKI > Python' 카테고리의 다른 글
collections 모듈 - Counter (0) | 2022.05.12 |
---|---|
vars() 내장함수 (0) | 2022.05.10 |
파이썬 리스트 컴프리헨션 (0) | 2022.05.04 |
Python 데코레이터 (0) | 2022.05.02 |
파이썬 property(), @property (0) | 2022.04.25 |
파이썬 비트 논리연산자 (0) | 2022.04.21 |
파이썬 정렬 함수 (rjust, ljust, zfill) (0) | 2022.04.20 |
[Python] 파이썬 인스턴스 메서드 / 정적 메서드 / 클래스 메서드 (0) | 2022.04.12 |