使用__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  怀心抱素  阅读(194)  评论(0编辑  收藏  举报