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中文网其他相关文章!