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读写Excel文件方法介绍
Nov 22 Python
python通过线程实现定时器timer的方法
Mar 16 Python
Django admin美化插件suit使用示例
Dec 12 Python
python 接口返回的json字符串实例
Mar 27 Python
Python系统监控模块psutil功能与经典用法分析
May 24 Python
通过 Django Pagination 实现简单分页功能
Nov 11 Python
python代码打印100-999之间的回文数示例
Nov 24 Python
PyCharm设置Ipython交互环境和宏快捷键进行数据分析图文详解
Apr 23 Python
Python flask框架实现浏览器点击自定义跳转页面
Jun 04 Python
基于pytorch中的Sequential用法说明
Jun 24 Python
Keras模型转成tensorflow的.pb操作
Jul 06 Python
拿来就用!Python批量合并PDF的示例代码
Aug 10 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
重料打造自己的“宝马”---第三代
2021/03/02 无线电
将RTF格式的文件转成HTML并在网页中显示的代码
2006/10/09 PHP
PHP 作用域解析运算符(::)
2010/07/27 PHP
深入extjs与php参数交互的详解
2013/06/25 PHP
php中__destruct与register_shutdown_function执行的先后顺序问题
2014/10/17 PHP
PHP中如何判断exec函数执行成功?
2016/08/04 PHP
jQuery选择头像并实时显示的代码
2010/06/27 Javascript
JavaScript—window对象使用示例
2013/12/09 Javascript
js调试系列 控制台命令行API使用方法
2014/06/18 Javascript
form.submit()不能提交表单的原因分析
2014/10/23 Javascript
node.js中的http.response.writeHead方法使用说明
2014/12/14 Javascript
JS闭包用法实例分析
2017/03/27 Javascript
angular实现IM聊天图片发送实例
2017/05/08 Javascript
详解前后端分离之VueJS前端
2017/05/24 Javascript
CKeditor富文本编辑器使用技巧之添加自定义插件的方法
2019/06/14 Javascript
vue组件开发之slider组件使用详解
2020/08/21 Javascript
[02:16]DOTA2超级联赛专访Burning 逆袭需要抓住机会
2013/06/24 DOTA
Python使用gensim计算文档相似性
2016/04/10 Python
Python Socket编程详细介绍
2017/03/23 Python
Python 修改列表中的元素方法
2018/06/26 Python
将tensorflow.Variable中的某些元素取出组成一个新的矩阵示例
2020/01/04 Python
使用Keras训练好的.h5模型来测试一个实例
2020/07/06 Python
Python读取Excel一列并计算所有对象出现次数的方法
2020/09/04 Python
CSS3实现DIV圆角效果完整代码
2012/10/10 HTML / CSS
html5用video标签流式加载的实现
2020/05/20 HTML / CSS
过程装备与控制工程专业个人的求职信
2013/12/01 职场文书
群众路线教育实践活动学习笔记内容
2014/11/06 职场文书
教师廉洁自律个人总结
2015/02/10 职场文书
民事起诉书范本
2015/05/19 职场文书
2015年音乐教师个人工作总结
2015/05/20 职场文书
物业保洁员管理制度
2015/08/05 职场文书
大学军训口号大全
2015/12/24 职场文书
2016年教师学习廉政准则心得体会
2016/01/20 职场文书
Python爬虫入门案例之回车桌面壁纸网美女图片采集
2021/10/16 Python
Python卷积神经网络图片分类框架详解分析
2021/11/07 Python
PYTHON基于Pyecharts绘制常见的直角坐标系图表
2022/04/28 Python