__slots__用于固定class里面打属性,一旦使用了__slots__,就只能使用设置好的属性了,而不能动态添加了
没有使用__slots__的class,实例化对象的是时候是使用的dict,而使用过的会将dict转成一个元组,我们都知道元组是不能修改的。有利于检索对象,因此加上__slots__的类,无需分配和使用dict
接下来,我们做一个实验,对比加上和没有加上的对象使用字节数量
使用__slots__
from pympler.asizeof import asizesof
class DaGongRen():#打工人
__slots__ = ('id_dg','age','salary')
def __init__(self,id_dg,age,salary):
self.id_dg=id_dg
self.age=age
self.salary=salary
#@profile
def test():
d=DaGongRen(10001,18,2000)
#print(asizesof(d.__dict__))
print(asizesof(d))
if __name__ == '__main__':
test()
运行结果:
[aspiree1431 opt]# python lru_cache.py
(152,)
不使用__slots__:
from pympler.asizeof import asizesof
class DaGongRen():#打工人
#__slots__ = ('id_dg','age','salary')
def __init__(self,id_dg,age,salary):
self.id_dg=id_dg
self.age=age
self.salary=salary
#@profile
def test():
d=DaGongRen(10001,18,2000)
#print(asizesof(d.__dict__))
print(asizesof(d))
if __name__ == '__main__':
test()
运行结果:
[aspiree1431 opt]# python lru_cache.py
(416,)
我们可以看到,使用__slots__后对象内存使用减少还是比较多
上面只是显示的是对象使用的内存,接下来准备对比一下使用__slots__后函数内存使用的情况:
使用__slots__:
from pympler.asizeof import asizesof
class DaGongRen():#打工人
__slots__ = ('id_dg','age','salary')
def __init__(self,id_dg,age,salary):
self.id_dg=id_dg
self.age=age
self.salary=salary
@profile
def test():
d=[ DaGongRen(10001,18,2000) for i in range(100000) ]
#print(asizesof(d.__dict__))
#print(asizesof(d))
if __name__ == '__main__':
test()
运行结果:
[aspiree1431 opt]# python -m memory_profiler lru_cache.py
Filename: lru_cache.py
Line # Mem usage Increment Occurences Line Contents
============================================================
32 33.656 MiB 33.656 MiB 1 @profile
33 def test():
34 40.809 MiB 7.152 MiB 100003 d=[ DaGongRen(10001,18,2000) for i in range(100000) ]
不使用__slots__:
from pympler.asizeof import asizesof
class DaGongRen():#打工人
#__slots__ = ('id_dg','age','salary')
def __init__(self,id_dg,age,salary):
self.id_dg=id_dg
self.age=age
self.salary=salary
@profile
def test():
d=[ DaGongRen(10001,18,2000) for i in range(100000) ]
#print(asizesof(d.__dict__))
#print(asizesof(d))
if __name__ == '__main__':
test()
运行结果:
[aspiree1431 opt]# python -m memory_profiler lru_cache.py
Filename: lru_cache.py
Line # Mem usage Increment Occurences Line Contents
============================================================
32 33.926 MiB 33.926 MiB 1 @profile
33 def test():
34 50.301 MiB 16.375 MiB 100003 d=[ DaGongRen(10001,18,2000) for i in range(100000) ]
我们可以发现,减少还是很多,不过好像看起来没有上面只是对象的时候比例高,这是因为对象只是函数里面的一部分,举个简单的例子。假如A有两个炒股账户A1+A2,A1基本上保持不变动,但是是占比最高,达到90%,而A2需要调整,但是占比10%,现在市场行情很好,A2翻了3倍,但是A的总账户能够翻3倍吗?
因此,我们在来做一个实验,减少迭代次数,然后会发现使用__slots__和不使用__slots__没啥区别
具体操作就是将上面的代码了里面的range(100000)里面减少一个0
#这个是使用了的
[aspiree1431 opt]# python -m memory_profiler lru_cache.py
Filename: lru_cache.py
Line # Mem usage Increment Occurences Line Contents
============================================================
32 33.129 MiB 33.129 MiB 1 @profile
33 def test():
34 33.129 MiB 0.000 MiB 1 d=DaGongRen(2,18,2000)
#这个是没有使用了的
[aspiree1431 opt]# python -m memory_profiler lru_cache.py
Filename: lru_cache.py
Line # Mem usage Increment Occurences Line Contents
============================================================
32 33.344 MiB 33.344 MiB 1 @profile
33 def test():
34 33.344 MiB 0.000 MiB 1 d=DaGongRen(2,18,2000)
这个实验可以说明,建对象需要很多的时候才能提升比较大,对于函数而已