Python类与对象学习心得-2:创建大量对象时节省内存的方法

如果你的程序要创建大量(可能上百万) 的对象,可能导致占用很大的内存,因为每个对象实例都保存自己专有的 __dict__ 字典。由于 Python 的字典采用散列表存储(类似于稀疏数组),它必然需要消耗额外的内存空间。

对于主要是用来当成简单的数据结构的类而言,你可以通过给类添加 __slots__ 属性来极大地减少对象实例所占的内存。比如:

class Date:
    __slots__ = ['year', 'month', 'day']

    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

当你定义 __slots__ 后,Python 就会为每个对象实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个字典,这跟元组或列表很类似。在 __slots__ 中列出的属性名在内部被映射到这个数组的指定下标上。使用 slots 一个不好的地方就是我们不能再给实例添加任何新的属性了,只能使用在 __slots__ 中定义的那些属性名

使用 slots 后节省的内存会跟存储属性的数量和类型有关。不过,一般来讲,使用到的内存总量和将数据存储在一个元组中差不多。为了给你一个直观认识,假设你不使用 slots 直接存储一个上面定义的 Date 实例,在 64 位的 Python 上面要占用 428 字节,而如果使用了 slots,内存占用下降到 156 字节。如果程序中需要同时创建大量的 Date 实例,那么这个就能极大地减小内存使用量了。

尽管 slots 看上去是一个很有用的特性,很多时候你还是得减少对它的使用冲动。Python 的很多特性都依赖于普通的基于字典的实现。另外,定义了 slots 后的类不再支持一些常见的类特性了,比如多继承(因为子类无法继承父类定义的 slots 属性)。大多数情况下,你应该只在那些经常被使用到的用作数据结构的类上定义 slots (比如在程序中需要创建某个类的几百万个实例对象)。

关于 __slots__ 的一个常见误区是它可以作为一个封装工具来防止用户给实例增加新的属性。尽管使用 slots 可以达到这样的目的,但是这个并不是它的初衷。__slots__ 机制的引入仅仅是用来作为一个内存优化工具

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值