파이썬 클래스 __slots__에 없는 속성이 왜 생성되는걸까요

조회수 561회
class b():
    __slots__=['a']
    c=1


one=b()
one.a=1
try:
    one.b=2
except:
    print("생성불가")

print(one.a)



class q():
    pass

class w(q):
    __slots__=['a']

two=w()
two.a=1
two.b=2
print(two.a, two.b)

b클래스에 slots 지정하여 a속성만 생성 가능하게 만들었고 그 외 속성 생성시 에러가 나옵니다

근데 q 클래스를 상속하는 w클래스는 slots에 없는 속성도 생성이 되는데 왜 가능하게 되는건가요? slots 없는 속성은 생성 불가능하게 어떻게 해야하나요?

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 파이썬에서 변수는 dict로 관리합니다.

    변수를 동적으로 추가하면 __dict__ 에 의해 dict로 변수들을 관리합니다. 이것이 mutable 이기 때문에 동적으로 넣을 수 있습니다.

    그런데 __slots__ 을 사용하면 __dict__ 를 제거합니다. 즉 동적으로 추가를 못하는 것이죠.

    문제는 side effect 가 크다는 겁니다. 기본 함수인 vars 도 사용못할 뿐더러 혹 외부모듈에서 객체의 __dict__ 를 필요로 한다면 오류가 발생합니다.

    __slots__ 잇점은 변수를 동적으로 못넣게 하는 것이 아니라 객체가 많을 경우 약간의 성능과 메모리를 아낄 수 있다는 겁니다. 동적인 언어에서 동적인 특징은 장점입니다.

    그러면 답을 이야기 해드리면...상속을 하면 부모, 자식 모든 클래스에 __slots__ 을 넣어야 합니다. 상속을 여러단계를 했을시 하나의 클래스라도 빼먹으면 원하는 동작을 기대할 수 없습니다.

    개인적으로는 얻는 것에 비해(객체를 많이 만들어야 한다면 이익이 됩니다만) 불필요한 기능이라고 생각하고 있습니다.

    class q():
        __slots__=['a']
    
    class w(q):
        __slots__=['b']
    
    
    two=w()
    two.a=1
    two.b=2
    #two.c=3    # error
    print(two.a, two.b)
    
    vars(two) # __dict__ 가 없다는 에러
    Traceback (most recent call last):
      File "<interactive input>", line 1, in <module>
    TypeError: vars() argument must have __dict__ attribute
    
    
    dir(two)    # __dict__ 는 없고 a, b 가 선언되어 있음
    ['__class__',
     '__delattr__',
     '__dir__',
     '__doc__',
     '__eq__',
     '__format__',
     '__ge__',
     '__getattribute__',
     '__gt__',
     '__hash__',
     '__init__',
     '__init_subclass__',
     '__le__',
     '__lt__',
     '__module__',
     '__ne__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__setattr__',
     '__sizeof__',
     '__slots__',
     '__str__',
     '__subclasshook__',
     'a',
     'b']
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)