您好,登錄后才能下訂單哦!
小編給大家分享一下Python3中類屬性slots的常見疑問以及解答示例,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
1.為什么 __slots__ 可以節省內存,提高速度的?
2.咋通過 __slots__ 來實現屬性的存儲與訪問的?
3.使用了 __slots__ 的類怎么實現動態賦值,如果需要實例弱引用支持怎么搞?
4.使用了 __slots__ 的類繼承與被繼承時的表現?
針對這幾個問題作答:
1. 通常情況下,類實例使用 __dict__來存儲其屬性數據,好處是允許我們在運行時動態的設置實例屬性,然而 dict 哈希表本身的數據結構決定了它需要更多的內存,當創建的實例越多,或者實例的屬性越多時,內存的耗費將更加嚴重。__slots__ 保證了解釋器在編譯時期就知道這個類具有什么屬性,以分配固定的空間來存儲已知的屬性。
2.使用 __slots__ 時,會將屬性的存儲從實例的 __dict__ 改為類的 __dict__ 中:
>>> Y.__dict__ mappingproxy({'__module__': '__main__', '__slots__': ('a', 'b'), '__init__': <function __main__.Y.__init__(self, a, b)>, 'a': <member 'a' of 'Y' objects>, 'b': <member 'b' of 'Y' objects>, '__doc__': None})
屬性的訪問是通過在類層級上為每個 slot 變量創建和 實現描述器(descriptor) 實現的,該描述器知道屬性值在實例列表中的唯一位置。關于描述器與屬性的訪問在我的 走進 Python 類的內部 一文中均有詳細的解釋,感興趣的同學可前去閱讀。另外,這篇 how __slots__ are implemented 也許可以幫助你的理解,盡管我看它寫于很多年前,但至今依然有借鑒意義。
3.怎么實現動態賦值和弱引用支持?答案是:在 __slots__ 中加上 __dict__ 和 __weakref__。
class Y: __slots__ = ('a', 'b', '__dict__', '__weakref__') def __init__(self, a, b): self.a = a self.b = b >>> import weakref >>> y = Y(7, 8) >>> y.a 7 >>> y.b 8 >>> y.c = 9 >>> y.__dict__ {'c': 9} >>> ry = weakref.ref(y) >>> ry <weakref at 0x107d17d68; to 'Y' at 0x107a4d480>
4.當類繼承自一個未定義 __slots__ 的類時,實例的 __dict__ 和 __weakref__ 屬性將總是可訪問的。
class X: def __init__(self): self.a = 7 class Y(X): __slots__ = ('b', 'c') def __init__(self): super().__init__() self.b = 8 self.c = 9 >>> y = Y() >>> y.a 7 >>> y.b 8 >>> y.__dict__ {'a': 7}
5.在父類中聲明的 __slots__ 在其子類中同樣可用。不過,子類將會獲得 __dict__ 和 __weakref__,除非它們也定義了 __slots__ 。
class X: __slots__=('a', 'b') def __init__(self): self.a = 7 self.b = 8 class Y(X): """沒有定義 __slots__""" class Z(X): __slots__ = () >>> y = Y() >>> y.a 7 >>> y.b 8 >>> y.c = 9 >>> y.__dict__ {'c': 9} >>> z = Z() >>> z.a 7 >>> z.b 8 >>> z.c = 9 AttributeError: 'Z' object has no attribute 'c'
以上是Python3中類屬性slots的常見疑問以及解答示例的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。