使用__slots__类属性节省空间
- 默认情况下,python在各个实例中名为
__dict__
的字典里存储实例属性。为了使用底层的散列表提升访问速度,字典会消耗大量内存。
- 如果要处理数百万个属性不多的实例,通过
__slots__
类属性,能节省大量内存,方法是让解释器在元组中存储实例属性,而不是用字典。
- 定义
__slots__
的方式是,创建一个类属性,使用__slots__
这个名字,并把它的值设为一个字符串构成的可迭代对象,其中各个元素表示各个实例属性。
我喜欢用元组,因为这样定义的__slots__
中所含的信息不会变化。
- 在类中定义
__slots__
属性的目的是告诉解释器:“这个类中所有实例属性都在这儿!”,这样,python会在各个实例中使用类似元组的结构存储实例变量,
从而避免使用消耗内存的__dict__
属性。如果有数百万个实例同时活动,这样做能节省大量内存。
- 在类中定义
__slots__
属性之后,实例不能再有__slots__
中所列名称之外的其他属性。这只是一个副作用,不是__slots__
存在的真正原因。
不要使用__slots__
属性禁止类的用户新增实例属性。__slots__
是用于优化的,不是为了约束程序员。
- 如果把
__dict__
这个名称添加到__slots__
中,实例会在元组中保存各个实例的属性,此外还支持动态创建属性,这些属性存储在常规的__dict__
中。
当然,把__dict__
添加到__slots__
中可能完全违背了初衷,这取决于各个实例的静态属性和动态属性的数量及其用法。粗心的优化甚至比提早优化还糟糕。
- 此外,还有一个实例属性需要注意,即
__weakref__
属性,为了让对象支持弱引用,必须有这个属性。用户定义的类中默认就有__weakref__
属性。
可是,如果类中定义了__slots__
属性,而且想把实例作为弱引用的目标,那么要把__weakref__
添加到__slots__
中。
- 综上,
__slots__
属性有些需要注意的地方,而且不能滥用,不能使用它限制用户能赋值的属性。
处理列表数据时__slots__
属性最有用,例如模式固定的数据库记录,以及特大型数据集。
posted @
2020-08-11 14:06
怀心抱素
阅读(
199)
评论()
编辑
收藏
举报