天天看點

python:__slots__屬性總結

__slots__屬性總結

*特點:

使用 slots 的注意事項

當繼承自一個未定義 slots 的類時,執行個體的 dict 和 weakref 屬性将總是可通路。

沒有 dict 變量,執行個體就不能給未在 slots 定義中列出的新變量指派。嘗試給一個未列出的變量名指派将引發 AttributeError。新變量需要動态指派,就要将 ‘dict’ 加入到 slots 聲明的字元串序列中。

如果未給每個執行個體設定 weakref 變量,定義了 slots 的類就不支援對其實際的弱引用。如果需要弱引用支援,就要将 ‘weakref’ 加入到 slots 聲明的字元串序列中。

slots 是通過為每個變量名建立描述器 (實作描述器) 在類層級上實作的。是以,類屬性不能被用來為通過 slots 定義的執行個體變量設定預設值;否則,類屬性就會覆寫描述器指派。

slots 聲明的作用不隻限于定義它的類。在父類中聲明的 slots 在其子類中同樣可用。不過,子類将會獲得 dict 和 weakref 除非它們也定義了 slots (其中應該僅包含對任何 額外 名稱的聲明位置)。

如果一個類定義的位置在某個基類中也有定義,則由基類位置定義的執行個體變量将不可通路(除非通過直接從基類擷取其描述器的方式)。這會使得程式的含義變成未定義。未來可能會添加一個防止此情況的檢查。

非空的 slots 不适用于派生自“可變長度”内置類型例如 int、bytes 和 tuple 的派生類。

任何非字元串可疊代對象都可以被指派給 slots。映射也可以被使用;不過,未來可能會分别賦給每個鍵具有特殊含義的值。

class 指派僅在兩個類具有相同的 slots 時才會起作用。

帶有多個父類聲明位置的多重繼承也是可用的,但僅允許一個父類具有由聲明位置建立的屬性(其他基類必須具有空的位置布局) —— 違反規則将引發 TypeError。

如果為 slots 使用了一個疊代器,則會為疊代器的每個值建立描述器。 但是 slots 屬性将為一個空疊代器。*

舉例說明:

#給類添加__slots__屬性實作在隻有__slots__變量中的實行才能被添加,沒有在__slots__變量中的屬性會添加失敗。可以防止其他人在調用類的時候胡亂添加屬性或方法。
#__slots__屬性子類不會繼承,隻有在目前類中有效


class Student(object):
    __slots__ = ('name','age')  
#以字元串的形式添加屬性  'score'   使用該方法可以節約記憶體空間
    def __str__(self):
        return '{}...{}'.format(self.name,self.age)
    pass
# zs=Student('張三',19)
zs=Student()
zs.name='張三'
zs.age=19
# zs.score=100    #因為在__slots__裡面沒有score屬性,是以動态添加後還是不能通路
# print(zs.__dict__)   #所有可以用到的屬性都在這裡存儲,不足的地方是占用的記憶體空間較大
print(zs)

#子類未聲明__solts__時,那麼是不會繼承父類的__solts__的,此時的子類是可以随意的屬性指派的
class subStudent(Student):
    # __slots__ = ('gender','job')     如果聲明了__solts__,那麼就會繼承父類的__solts__ 裡面限定的屬性盡量不要跟父類的重複,因為會消耗記憶體空間
    pass
ln=subStudent()
ln.gender='男'
ln.job='計算機科學'
print(ln.gender,ln.job)
           

結果:

python:__slots__屬性總結