파이썬에서 __slots__를 사용하는 방법과 시기

각 파이썬 개체에는 다음을 포함하는 사전인 _dict_ 속성이 있습니다.
다른 모든 속성. 예를 들어 self.attr을 입력하면 Python이 실제로
self.dict['attr'].

속성을 저장하기 위해 사전을 사용하는 것을 상상할 수 있듯이 약간의 추가 공간이 필요합니다.
& 액세스 시간입니다.

클래스가 갖게 될 속성을 이미 알고 있다면 어떨까요? 그 다음에
_dict_를 사용하여 속성을 저장하는 것은 좋은 생각이 아닌 것 같습니다.
dicts의 동적 특성이 필요합니다.

이것은 슬롯이 구출되는 곳입니다.

파이썬에서 슬롯이란 무엇입니까



_slots_는 우리가 a의 속성을 선언할 수 있게 해주는 클래스 변수입니다.
명시적으로 클래스를 만들고 _dict_ 생성을 거부하고
개체 인스턴스에 대한 _weakref_ .

예상되는 속성은 _slots_에 문자열, 반복 가능,
또는 인스턴스에서 사용하는 변수 이름이 있는 일련의 문자열입니다.

_dict_를 사용하지 않음으로써 절약된 공간은 상당할 수 있습니다. 슬롯도
속성 조회 속도를 향상시킵니다.

슬롯 사용



Python은 훨씬 더 간결한 내부 표현을 활용합니다.
_slots_를 정의할 때의 인스턴스. 사전 대신 각 인스턴스
튜플이나 목록과 유사한 작은 고정 크기 배열 주위에 생성됩니다.

슬롯을 사용한 결과 더 이상 새 속성을 추가할 수 없습니다.
인스턴스;
_slots_ 지정자에 지정된 속성 이름으로 제한됩니다.(
_slot_에 _dict_를 추가하여 이 문제를 해결할 수 있습니다. 딕셔너리는
동적 속성이 추가되면 초기화됨).

슬롯 사용을 보여주는 예:


# A email class with out using slots

class Email :
  def __init__(self,subject,to,message) :
    self.subject = subject
    self.message = message
    self.to = to


class EmailWithSlots :

  __slots__ = ('subject','to','message')

  def __init__(self,subject,to,message) :
    self.subject = subject
    self.message = message
    self.to = to


email = EmailWithSlots('test','[email protected]','testing slots')

email.subject
# >> test

email.__dict__  # cant access __dict__ because its not created


# AttributeError                            Traceback (most recent call last)
# <ipython-input-40-b95667a7fb92> in <module>
#  ----> 1 email.__dict__
#
#AttributeError: 'EmailWithSlots' object has no attribute '__dict__'

email.from = "[email protected]" # cant add an atribute that not in __slots__

# ---------------------------------------------------------------------------
# AttributeError                            Traceback (most recent call last)
# <ipython-input-42-87651e4df821> in <module>
# ----> email.from = "[email protected]"
#
#AttributeError: 'EmailWithSlots' object has no attribute 'from'





슬롯의 장단점



장점


  • _slots_를 사용하면 속성에 더 빠르게 액세스할 수 있습니다.
  • _slots_는 메모리 사용량을 줄입니다
  • .

    단점


  • 고정 속성( _dict_를
    _슬롯_ . 사전은 동적 속성이 추가된 경우에만 초기화됩니다.)
  • _슬롯_은 설명자를 생성하여 클래스 수준에서 구현됩니다.
    각 변수 이름에 대해. 결과적으로 클래스 속성을 사용하여 설정할 수 없습니다.
    _slots_에 의해 정의된 인스턴스 변수의 기본값; 그렇지 않으면
    class 속성은 설명자 할당을 덮어씁니다.

  • 슬롯 상속 .



    슬롯 및 상속 작업은 약간 까다로우며 주의가 필요합니다.
    의 . 방법은 다음과 같습니다.
  • 상위 클래스에 정의된 _slots_는 자동으로
    어린이 .

  •    class BaseClass :
           __slots__ = ['x','y','z']
    
    
       class Inherited(BaseClass) :
            pass
    
    
       Inherited.__slots__
    
       #>> ['x', 'y', 'z']
    
    

  • 하위 클래스가 슬롯을 지정하지 않는 경우(empty 또는 new). 하위 클래스는
    부모의 슬롯 외에 _dict_ 및 _weakref_ 속성 가져오기

  •    class BaseClass :
           __slots__ = ['x','y','z']
    
    
       class Inherited(BaseClass) :
            pass
    
       class InheritedWithSlots(BaseClass) :
          __slots__ = ()
    
       Inherited.__slots__
       #>> ['x', 'y', 'z']
    
       Inherited.__dict__
       #>> {}
    
       InheritedWithSlots().__dict__
       # AttributeError
    
    


  • 비어 있지 않은 _slots_는 int, bytes 및 tuple과 같은 "가변 길이"내장 유형에서 파생된 클래스에 대해 작동하지 않습니다.

    
    # this works fine because we are not using any additional slots in subclass
    class MyInt(int):
        __slots__ = ()
    
    # This will panic because we are adding non-empty slots .
    class NewInt(int) :
        __slots__ = (x,y)
    
    #TypeError: nonempty __slots__ not supported for subtype of 'int'
    
    




  • 슬롯과 함께 다중 상속을 사용할 수도 있습니다. 하지만 부모 중 한 명만 가능
    비어 있지 않은 _slots_가 있습니다. 그렇지 않으면 typeerror가 발생합니다.

    
    #lets have three slotted base classes
    
    class foo:
      __slots__ = ("x","y")
    
    class bar :
      __slots__ = ("a","b")
    
    class baz :
       __slots__=()
    
    # this will raise TypeError as we are inheriting from two classes
    # with nonempty slots
    class foobar(foo,bar) :
      pass
    
    #>>TypeError: multiple bases have instance lay-out conflict
    
    # This shall work as only one of the inherited class has nonempty slots
    
    class FooBaz(foo,bar) :
      pass
    
    



  • 결론 :



    _slots_는 어떤 인스턴스 변수가 예상되는지 명시적으로 명시할 수 있게 해줍니다.
    그 물체

    다음과 같은 이점이 있습니다.
  • 빠른 속성 액세스
  • 메모리 절약

  • 일반적인 사용 사례



    주로 단순한 데이터 구조로 사용되는 클래스의 경우 종종 크게 줄일 수 있습니다.
    _slots_ 속성을
    클래스 정의.

    슬롯이 나쁜 생각일 때.


  • 슬롯 레이아웃이 동일하지 않은 한 슬롯이 없는 다른 클래스로 _class_ 할당을 수행하려는 경우(그리고 추가할 수 없음) 이를 피하십시오. (누가 왜 이런 일을 하는지 알고 싶습니다.)
  • long, tuple 또는 str과 같은 가변 길이 내장 기능을 서브클래싱하고 속성을 추가하려는 경우 이를 사용하지 마십시오.
  • 인스턴스 변수에 대한 클래스 속성을 통해 기본값을 제공하려는 경우 이를 피하십시오.

  • 끝까지 읽어 주셔서 감사합니다 행복한 코딩 ..

    좋은 웹페이지 즐겨찾기