簡介
在廖雪峰的python網站上,他是這么說的
python是動態語言,它允許程序在執行過程中動態綁定屬性或者方法(使用MethodTpye)。
某個實例在執行過程中綁定的屬性跟方法,僅在該實例中有效,其他同類實例是沒有的。
可以通過給class綁定屬性/方法,來給所有實例綁定屬性/方法:
Student.name = ''Student.set_score = set_score
而如果使用__slots__,它僅允許動態綁定()里面有的屬性
例如,下面這樣會報錯
class Student():__slots__ = ('name', 'age')S1 = Student()S1.name = 'Jack' # ok!S1.score = 123 # error!
但是我覺得很奇怪,僅有這一個作用嗎?于是我再查了其他資料,發現這個函數可以很可觀地節約內存,下面來一起看看詳細的介紹吧。
__slots__允許我們聲明并限定類成員,并拒絕類創建__dict__和__weakref__屬性以節約內存空間。
Python是動態語言,對于普通的類,可以為類實例賦值任何屬性,這些屬性會存儲在__dict__中:
>>> class Student(object):... pass... >>> Abey = Student()>>> Abey.name = 'Abey'>>> Abey.__dict__{'name': 'Abey'}
這樣的特性帶來兩個問題:
數據通過字典(Hash)存儲所占用的空間較大 如何禁止隨意生成類屬性當然,__slots__就能解決這兩個問題。通過__slots__屬性限定類屬性的創建:
>>> class Student(object):... __slots__ = ('name', 'age')... >>> Abey = Student()>>> Abey.name = 'Abey'>>> Abey.gender = 'Female'Traceback (most recent call last): File "<input>", line 1, in <module>AttributeError: 'Student' object has no attribute 'gender'>>> Abey.__dict__Traceback (most recent call last): File "<input>", line 1, in <module>AttributeError: 'Student' object has no attribute '__dict__'
可以看到,在定義了__slots__變量后,Student類實例已經不能隨意創建不在__slots__定義內的屬性gender,同時實例中也不再有__dict__結構。
用法
繼承樹
__slots__在繼承中有兩種表現:
子類未聲明__slots__時,不繼承父類的__slots__,即此時子類實例可以隨意賦值屬性 子類聲明__slots__時,繼承父類的__slots__,即此時子類的__slots__為其自身+父類的__slots__以下面的父類為例:
>>> class Student(object):... __slots__ = ('name', 'age')...
創建一個子類不聲明__slots__,該類實例可以創建父類__slots__限定之外的屬性gender:
>>> class SubStudent(Student):... pass... >>> Bob = SubStudent()>>> Bob.gender = 'Male'>>> Bob.__dict__{'gender': 'Male'}
新聞熱點
疑難解答