python之__slots__方法使用

python版本:3.6
1、__slots__的作用
一般情况下,Python允许在程序运行时给对象绑定新的属性或方法。但是,如果我们要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定,这相当于告诉解释器,实例的属性都叫什么,并且只能有这些属性,在定义时,推荐__slots__使用元组,而不是列表,这样做可以节省内存,__slots__的限定只对当前类的对象生效,对子类并不起任何作用。
2、实例:
本文章仅供学习做记录,如有侵权,告知删除。

本例中使用了__slots__,__dict__,内存统计方法的使用。关于__dict__方法的使用,在下一篇介绍。
import sys
import tracemalloc


class Person1(object):
    def __init__(self, pid, name, age):
        self.pid = pid
        self.name = name
        self.status = age


class Person2(object):
    __slots__ = ("pid", "name", "age")

    def __init__(self, pid, name, age):
        self.pid = pid
        self.name = name
        self.age = age


if __name__ == '__main__':
    p1 = Person1("111","p1","20")
    p2 = Person2("222","p2","30")
    p1.__dict__["level"] = 10 # __dict__ 为对象动态绑定属性,为对象p1 绑定新属性level {'pid': '111', 'name': 'p1', 'status': '20', 'level': 10}
    print(p1.__dict__) # p1.__dict__  打印的是当前对象所具有属性,是一个字典
    print(sys.getsizeof(p1.__dict__))
    # p2.__dict__["level"] = 20   # 会报错,p2不能绑定新属性,因为在Person2中使用了__slots__ = ()约定了三个属性

    tracemalloc.start() # 开始跟踪内存分配
    p1 = [Person1(23,24,25) for _ in range(100000)]
    p2 = [Person2(30,31,32) for _ in range(100000)]
    snapshot = tracemalloc.take_snapshot()
    top = snapshot.statistics("filename")
    for start in top[:10]:
        print(start)

返回结果:

{'pid': '111', 'name': 'p1', 'status': '20', 'level': 10}
112
E:/pytestcode/slotstest.py:0: size=23.7 MiB, count=400004, average=62 B
D:\Python36\lib\tracemalloc.py:0: size=64 B, count=1, average=64 B

从返回结果中可以看出,使用__slots__ 定义一个元组,产生的对象占用的内存要小的多。
另外,在本例中我把__slots__ 定义为为一个列表和定义为一个元组,占用的内存大小差不多,这是在测试代码中。如果在正式的程序中,可能会提现的更明显。

当给p2另外绑定新属性时,会报错,如下:

Traceback (most recent call last):
  File "E:/pytestcode/slotstest.py", line 27, in <module>
    p2.__dict__["level"] = 20   # 会报错,p2不能绑定新属性,因为在Player2中使用了__slots__ = ()约定了三个属性
AttributeError: 'Person2' object has no attribute '__dict__'
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值