Python对象中一般会有一个__dict__属性,负责存储对象的属性,当为对象动态地赋予属性时,也是在__dict__中添加该属性:
In [44]: class PythonObject(object):
...: pass
...:
In [45]: o = PythonObject()
In [46]: o.__dict__
Out[46]: {}
In [47]: o.new_attr = 'new attr'
In [48]: o.__dict__
Out[48]: {
'new_attr': 'new attr'}
__dict__属性是通过Python dict来实现的,原理上即hash table,因此默认会保留多余的空间(hash table装载因子超过2/3的时候需要扩容)。如果一个Python对象不需要动态赋值属性,并且该Python对象所属的类需要很多实例化对象的时候,那么__dict__造成的内存开销就会比较大,此时可以考虑使用__slots__属性来减小内存的开销。
可以在__slots__属性中定义该Python对象需要的属性,此时如果为Python对象动态赋予未在__slots__定义的属性,就会raise AttributeError。
In [49]: class SlotClass(object):
...: __slots__ = ('attr1', 'attr2')
...:
In [50]: s = SlotClass()
In [51]: s.attr1 = 'attr1'
In [52]: s.attr1
Out[52]: 'attr1'
In [53]: s.attr3 = 'can not assign'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-53-901ed201a4ae> in <module>()
----> 1 s.attr3 = 'ca