Python中的__slots__示例详解


Posted in Python onJuly 06, 2017

前言

相信Python老鸟都应该看过那篇非常有吸引力的Saving 9 GB of RAM with Python's slots 文章,作者使用了__slots__让内存占用从25.5GB降到了16.2GB。在当时来说,这相当于用一个非常简单的方式就降低了30%的内存使用,着实惊人。作者并没有提到他的业务特点和代码,那我们就基于《fluent python》中的例子来验证下是不是有这么厉害:

from __future__ import print_function
import resource
class A(object):
 def __init__(self):
 self.a = 'string'
 self.b = 10
 self.c = True
class B(object):
 __slots__ = ['a', 'b', 'c']
 def __init__(self):
 self.a = 'string'
 self.b = 10
 self.c = True
def test(cls):
 mem_init = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
 l = []
 for i in range(500000):
 l.append(cls())
 mem_final = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
 del l
 print('Class: {}:\n'.format(getattr(cls, '__name__')))
 print('Initial RAM usage: {:14,}'.format(mem_init))
 print(' Final RAM usage: {:14,}'.format(mem_final))
 print('-' * 20)
if __name__ == '__main__':
 import sys
 test(globals()[sys.argv[1].upper()])

我们分别跑一下这2个类:

❯ python mem_test.py a
Class: A:
Initial RAM usage: 4,890,624
 Final RAM usage: 200,454,144
--------------------
❯ python mem_test.py b
Class: B:
Initial RAM usage: 4,919,296
 Final RAM usage: 60,235,776

2种方法初始内存略有差别,但是由于这个差别和总内存量相比太小而忽略不计,结论就是:

使用slots可以让内存使用减少3.5倍!!# 通过 (200 - 4) / ((60 - 4) * 1.0) 计算得来

那么用slot就是非非常那个有必要吗?事实上500000个实例这种机会非常少见,用不用完全根据业务来决定,并不要以偏概全。因为(敲黑板了哈)使用__slots__也是有副作用的:

  1. 每个继承的子类都要重新定义一遍__slots__
  2. 实例只能包含哪些在__slots__定义的属性,这对写程序的灵活性有影响,比如你由于某个原因新网给instance设置一个新的属性,比如instance.a = 1, 但是由于a不在__slots__里面就直接报错了,你得不断地去修改__slots__或者用其他方法迂回的解决
  3. 实例不能有弱引用(weakref)目标,否则要记得把__weakref__放进__slots__

第三点有点难理解,我写个例子看看吧:

In [2]: %pycat ref_example.py
from weakref import ref
class A(object):
 __slots__ = ['b']
 def __init__(self):
 self.b = 1
class B(object):
 __slots__ = ['b', '__weakref__']
 def __init__(self):
 self.b = 1
In [3]: from ref_example import *
In [4]: a = A()
In [5]: r = ref(a)
---------------------------------------------------------------------------
TypeError     Traceback (most recent call last)
<ipython-input-6-75a6d689c8b3> in <module>()
----> 1 r = ref(a)
TypeError: cannot create weak reference to 'A' object
In [6]: b = B()
In [7]: r = ref(b)
In [8]: r
Out[8]: <weakref at 0x109199578; to 'B' at 0x10919f890>

所以实例不超过万级别的类,__slots__是不太值得使用的。

PS: 《fluent python》比我狠,说的是小于百万级别实例不值得使用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python实现求最大公约数及判断素数的方法
May 26 Python
Python中列表和元组的使用方法和区别详解
Dec 30 Python
Python实现的本地文件搜索功能示例【测试可用】
May 30 Python
PyCharm代码整体缩进,反向缩进的方法
Jun 25 Python
对python Tkinter Text的用法详解
Oct 11 Python
python 用opencv调用训练好的模型进行识别的方法
Dec 07 Python
对python多线程中互斥锁Threading.Lock的简单应用详解
Jan 11 Python
用python拟合等角螺线的实现示例
Dec 27 Python
Python第三方库的几种安装方式(小结)
Apr 03 Python
Python发送邮件封装实现过程详解
May 09 Python
协程Python 中实现多任务耗资源最小的方式
Oct 19 Python
python字符串的一些常见实用操作
Apr 06 Python
利用python获取Ping结果示例代码
Jul 06 #Python
Python中工作日类库Busines Holiday的介绍与使用
Jul 06 #Python
Python中动态检测编码chardet的使用教程
Jul 06 #Python
Python解析json之ValueError: Expecting property name enclosed in double quotes: line 1 column 2(char 1)
Jul 06 #Python
CentOS 7下Python 2.7升级至Python3.6.1的实战教程
Jul 06 #Python
Python中定时任务框架APScheduler的快速入门指南
Jul 06 #Python
Python如何快速实现分布式任务
Jul 06 #Python
You might like
ASP和PHP都是可以删除自身的
2007/04/09 PHP
PHP的cURL库功能简介 抓取网页、POST数据及其他
2011/04/07 PHP
thinkPHP5.0框架环境变量配置方法
2017/03/17 PHP
php提交表单时保留多个空格及换行的文本样式的方法
2017/06/20 PHP
理解Javascript_09_Function与Object
2010/10/16 Javascript
jQuery EasyUI API 中文文档 - Calendar日历使用
2011/10/19 Javascript
JS函数实现动态添加CSS样式表文件
2012/12/15 Javascript
js 程序执行与顺序实现详解
2013/05/13 Javascript
js实现获取div坐标的方法
2015/11/16 Javascript
JS获取数组最大值、最小值及长度的方法
2015/11/24 Javascript
第二章之Bootstrap 页面排版样式
2016/04/25 Javascript
用NodeJS实现批量查询地理位置的经纬度接口
2016/08/16 NodeJs
JavaScript实现DOM对象选择器
2016/09/24 Javascript
vue.js的手脚架vue-cli项目搭建的步骤
2017/08/30 Javascript
js中getBoundingClientRect的作用及兼容方案详解
2018/02/01 Javascript
js+canvas实现纸牌游戏
2020/03/16 Javascript
解决antd 表单设置默认值initialValue后验证失效的问题
2020/11/02 Javascript
python将多个文本文件合并为一个文本的代码(便于搜索)
2011/03/13 Python
Python中Django框架下的staticfiles使用简介
2015/05/30 Python
详解python之配置日志的几种方式
2017/05/22 Python
利用Python如何实现一个小说网站雏形
2018/11/23 Python
用Python配平化学方程式的方法
2019/07/20 Python
python代码实现逻辑回归logistic原理
2019/08/07 Python
Python基于execjs运行js过程解析
2020/11/27 Python
Python3.8.2安装包及安装教程图文详解(附安装包)
2020/11/28 Python
python pyg2plot的原理知识点总结
2021/02/28 Python
基于HTML5的齿轮动画特效
2016/02/29 HTML / CSS
澳洲本土太阳镜品牌:Quay Australia
2019/07/29 全球购物
介绍一下#error预处理
2015/09/25 面试题
公务员年总结的自我评价
2013/10/25 职场文书
财务人员求职自荐书范文
2014/02/10 职场文书
租房协议书怎么写
2014/04/10 职场文书
2014党员批评和自我批评思想汇报
2014/09/21 职场文书
毕业生自荐信范文
2015/03/05 职场文书
医院岗前培训心得体会
2016/01/08 职场文书
SQL Server——索引+基于单表的数据插入与简单查询【1】
2021/04/05 SQL Server