Python中的插槽屬性是一種用於在類級別明確聲明數據屬性(實例變量)的工具,這可以導致更有效的內存使用和更快的屬性訪問。當一個類定義__slots__
屬性時,Python為類的每個實例創建一個小的固定大小數組,而不是使用動態詞典來存儲實例屬性。該機制有幾個目的:
__slots__
,未創建實例的__dict__
,這可以保存內存,尤其是在處理大量實例時。__slots__
啟用類中的訪問屬性比訪問基於標準字典的實例中的屬性更快,因為它避免了字典查找的開銷。__slots__
時,python將新屬性的創建限制為__slots__
中定義的那些,除非__dict__
__slots__
這是如何使用__slots__
:
<code class="python">class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y</code>
__slots__
的使用可以提供幾種績效好處:
__slots__
用固定大小的數組替換實例的__dict__
,因此可以大大減少實例的內存足跡。在創建大量實例時,這特別有益。__slots__
中定義的屬性可以比詞典中存儲的屬性更快地訪問。這是因為在小固定尺寸陣列中訪問元素通常比執行字典查找要快。__slots__
實例,因為隨後的參考文獻較少。為了說明這些好處,請考慮以下示例:
<code class="python">import sys class StandardPoint: def __init__(self, x, y): self.x = x self.y = y class SlotPoint: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y standard = StandardPoint(1, 2) slot = SlotPoint(1, 2) print(sys.getsizeof(standard)) # Output may be around 56 bytes print(sys.getsizeof(slot)) # Output may be around 32 bytes</code>
在此示例中, SlotPoint
實例使用的內存少於StandardPoint
實例。
使用__slots__
通過以下方式影響屬性分配:
__slots__
時,只能將__slots__
中列出的屬性分配給一個實例。試圖分配不在__slots__
中的屬性會產生AttributeError
,除非__dict__
包含在__slots__
中。__dict__
: By default, instances of classes with __slots__
do not have a __dict__
. This means dynamic attribute assignment is disabled unless __dict__
is explicitly included in __slots__
.__weakref__
:如果類需要支持弱參考,則__weakref__
必須包含在__slots__
。這是一個證明這些效果的示例:
<code class="python">class RestrictedPoint: __slots__ = ('x', 'y') point = RestrictedPoint() point.x = 10 # This is allowed point.y = 20 # This is allowed try: point.z = 30 # This will raise an AttributeError except AttributeError as e: print(e) # Output: 'RestrictedPoint' object has no attribute 'z'</code>
是的, __slots__
可以與繼承結合使用,但是要記住幾個考慮因素:
__slots__
,它將從其超類繼承插槽,但前提是超級類也定義__slots__
。如果超級階級不使用__slots__
,則其實例仍將使用__dict__
,這可能導致內存效率低下。__dict__
:如果子類想要允許動態屬性,則可以在其__slots__
中包含__dict__
。但是,這可能首先會打敗使用__slots__
的避免內存的目的。__slots__
使用多個繼承時,所有類都必須定義__slots__
或從定義__slots__
類中繼承。如果一個父類不使用__slots__
,則子類的實例仍將具有__dict__
。這是一個說明這些考慮因素的示例:
<code class="python">class Base: __slots__ = ('x',) class Derived(Base): __slots__ = ('y',) # Inherits 'x' from Base derived = Derived() derived.x = 10 # Inherited from Base derived.y = 20 # Defined in Derived class FlexibleDerived(Base): __slots__ = ('y', '__dict__') # Allows dynamic attributes flexible = FlexibleDerived() flexible.x = 10 # Inherited from Base flexible.y = 20 # Defined in FlexibleDerived flexible.z = 30 # Dynamic attribute, allowed because of __dict__</code>
總之,雖然__slots__
可以通過繼承有效地使用,但需要仔細的計劃,以確保在整個層次結構中實現所需的內存優化和屬性行為。
以上是說明__slots__屬性的目的。的詳細內容。更多資訊請關注PHP中文網其他相關文章!