1. 程式人生 > 其它 >Python面向物件程式設計進階2之__slots__魔法

Python面向物件程式設計進階2之__slots__魔法

開始Python的複習!(以前學的忘了好多-_-)
主要參考的是Github上的一個專案:https://github.com/jackfrued/Python-100-Days
文章主要是對該專案中的內容進行學習 穿插一點自己的學習想法等內容~

作為一門動態語言,可以新增屬性 方法,自然也應該有刪除屬性 方法功能。如果我們需要限定自定義型別的物件只能繫結某些屬性,可以通過在類中定義__slots__變數來進行限定。該類限定只對當前類的物件生效,對子類不起任何作用。

__slots__魔法

class Person(object):
    # 限定Person物件只能繫結_name, _age和_gender屬性
    __slots__ = ('_name', '_age', '_gender')

    def __init__(self, name, age):
        self._name = name
        self._age = age

__slots__出現的原因來啦~
Python是動態語言,對於普通的類,可以為類例項賦值任何屬性,這些屬性會儲存在__dict__中,但資料通過字典(Hash)儲存所佔用的空間較大,效率較低,__slots__屬性的出現就是為了解決上述問題。
__slots__屬性的作用是宣告並限定類成員,並拒絕類建立__dict__和__weakref__屬性以節約記憶體空間。

字面來看是為了限制隨意新增屬性,造成混亂。但實際上如果瞭解過Python底層的實現原理,你會發現在Python當中為每一個例項都建立了一個字典,就是大名鼎鼎的__dict__字典。正是因為背後有一個字典,所以我們才可以創造出原本不存在的成員,也才支援這樣動態的效果。

我們可以人工地呼叫這個字典輸出其中的內容,我們在加上__slots__關鍵字之前,輸出的結果是這樣的:{'a': None, 'b': None}
但是加上了這個關鍵字之後,會得到一個報錯,會告訴你Exp這個物件當中沒有__dict__這個成員。原因很簡單,因為使用dict來維護例項,會消耗大量的記憶體,額外儲存了許多資料,而使用__slots__之後,Python內部將不再為例項建立一個字典來維護,而是會使用一個固定大小的陣列,這樣就節省了大量的空間。這個節省可不是一點半點,一般可以節省一半以上。也就是說犧牲了一定的靈活性,保證了效能。這一點也是__slots__這個關鍵字設計的初衷,但是現在很多人都用錯了地方。【實際上之前還看到一篇帖子有人做了實驗,在百萬資料量以下 這個方法沒有顯著優勢】

參考連結

https://zhuanlan.zhihu.com/p/134128022