프로그래밍백엔드 Python 개발자

Python 클래스에서 __slots__란 무엇이며, 왜 필요한지, 그리고 그 제한은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

__slots__는 클래스의 특별한 속성으로, 인스턴스의 허용 속성 집합을 제한하고, 메모리를 절약하며, 속성 접근 속도를 높여줍니다. __slots__의 사용은 특히 대량의 유사 객체에 유용합니다.

문제의 역사:

__slots__의 등장은 기본적으로 각 Python 객체 인스턴스에 속성 딕셔너리(__dict__)가 존재함에 따라 발생합니다. 이는 편리하지만 메모리 측면에서 비용이 많이 듭니다. 적은 수의 필드로 백만 개의 객체에 대해 상당한 오버헤드가 발생합니다.

문제:

일반 클래스 인스턴스는 동적으로 확장될 수 있어 편리하지만 비효율적입니다. __slots__의 사용은 새로운 속성의 동적 추가를 제한하고, 인스턴스 속성 딕셔너리를 제거하여 메모리를 절약하고 접근 속도를 향상시킵니다.

해결책:

__slots__ 속성에 허용된 필드 목록을 명시해야 합니다:

class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y p = Point(1, 2) p.z = 3 # AttributeError: 'Point' 객체에 'z' 속성이 없습니다.

주요 특징:

  • 기본적으로 __dict__와 __weakref__가 없어서 메모리를 절약합니다.
  • 허용된 필드의 엄격한 집합을 정의합니다.
  • 미리 할당된 슬롯 덕분에 속성 접근 속도를 높입니다 (딕셔너리 검색이 필요하지 않음).

함정 질문.

__slots__가 있는 클래스 인스턴스를 생성한 후 목록에 없는 속성을 추가할 수 있습니까?

아니요. __slots__ 목록에 없는 속성을 추가하려고 하면 AttributeError가 발생합니다. 이는 객체의 확장성에 대한 제한을 부과합니다.

__slots__가 있는 클래스를 상속받아 새로운 필드를 추가할 수 있습니까?

네, 그러나 각 자식 클래스는 자신의 __slots__를 선언해야 합니다. 부모와 현재 __slots__는 결합됩니다. 단, 자식 클래스에서 __slots__를 선언하지 않으면 자식에게 다시 __dict__가 생깁니다!

__slots__는 변경 불가능(immutable) 유형에 대해 작동합니까?

네, 하지만 슬롯 객체를 변경 불가능하게 만들기 위한 추가 조치를 구현해야 합니다 (예: 세터 없는 property를 통해).

일반적인 오류 및 반패턴

  • 자식 클래스에서 __slots__를 선언하지 않아 메모리 효율성이 깨짐.
  • 다중 상속이 있을 경우 __slots__의 작동을 기대함 — 충돌 및 오류가 발생할 수 있음.
  • 슬롯을 가진 객체를 표준 방법으로 직렬화하는 것이 때때로 어렵습니다 (예: pickle은 __dict__가 필요함).

실제 사례

부정적 사례

점에 대한 일반 클래스:

class Point: def __init__(self, x, y): self.x = x self.y = y points = [Point(i, i) for i in range(1_000_000)]

장점:

  • 유연함 — 원하는 속성을 추가할 수 있음.
  • 초보자에게 이해하기 쉬움.

단점:

  • 작업 관리자에서 메모리 소비가 현저히 증가함 (최대 +20-30%).

긍정적 사례

슬롯이 있는 유사한 클래스:

class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y points = [Point(i, i) for i in range(1_000_000)]

장점:

  • 수백만 객체에서 최대 30% 메모리 절약.
  • 필드 접근이 더 빠름.

단점:

  • 객체가 유연하지 않음: 새로운 속성을 추가할 수 없음.