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配置文件解析模块ConfigParser使用实例
Apr 13 Python
python中lambda与def用法对比实例分析
Apr 30 Python
Python中列表元素转为数字的方法分析
Jun 14 Python
Python的Flask框架中使用Flask-Migrate扩展迁移数据库的教程
Jun 14 Python
python 连接各类主流数据库的实例代码
Jan 30 Python
python版大富翁源代码分享
Nov 19 Python
python实现爬取百度图片的方法示例
Jul 06 Python
如何通过50行Python代码获取公众号全部文章
Jul 12 Python
Django model 中设置联合约束和联合索引的方法
Aug 06 Python
关于Tensorflow分布式并行策略
Feb 03 Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
May 10 Python
Scrapy项目实战之爬取某社区用户详情
Sep 17 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
第三章 php操作符与控制结构代码
2011/12/30 PHP
详解php几行代码实现CSV格式文件输出
2017/07/01 PHP
一些有关检查数据的JS代码
2006/09/07 Javascript
JavaScript 对象链式操作测试代码
2010/04/25 Javascript
js监听键盘事件示例代码
2013/07/26 Javascript
判断文件是否正在被使用的JS代码
2013/12/21 Javascript
jquery选择器之属性过滤选择器详解
2014/01/27 Javascript
JS中三目运算符和if else的区别分析与示例
2014/11/21 Javascript
jQuery结合CSS制作动态的下拉菜单
2015/10/27 Javascript
jQuery中inArray方法注意事项分析
2016/01/25 Javascript
浅谈MVC+EF easyui dataGrid 动态加载分页表格
2016/11/10 Javascript
纯js模仿windows系统日历
2017/02/04 Javascript
Angular 2 利用Router事件和Title实现动态页面标题的方法
2017/08/23 Javascript
Chrome调试折腾记之JS断点调试技巧
2017/09/11 Javascript
jQuery实现模拟搜索引擎的智能提示功能简单示例
2019/01/27 jQuery
vue实现微信分享链接添加动态参数的方法
2019/04/29 Javascript
JavaScript面向对象编程小游戏---贪吃蛇代码实例
2019/05/15 Javascript
关于JS解构的5种有趣用法
2019/09/05 Javascript
Python笔记(叁)继续学习
2012/10/24 Python
在Django中创建URLconf相关的通用视图的方法
2015/07/20 Python
Python实现简单的文本相似度分析操作详解
2018/06/16 Python
使用python turtle画高达
2020/01/19 Python
python词云库wordcloud的使用方法与实例详解
2020/02/17 Python
Jupyter Notebook远程登录及密码设置操作
2020/04/10 Python
Python发送邮件实现基础解析
2020/08/14 Python
HTML5视频播放插件 video.js介绍
2018/09/29 HTML / CSS
阿根廷网上配眼镜:SmartBuyGlasses阿根廷
2016/08/19 全球购物
瑞典时尚服装购物网站:Miinto.se
2017/10/30 全球购物
英国最大的LED专业零售商:Led Hut
2018/03/16 全球购物
Sandro法国官网:法国成衣品牌
2019/08/28 全球购物
初中女生自我鉴定
2013/12/19 职场文书
师德师风自查材料
2014/10/14 职场文书
保研专家推荐信范文
2015/03/25 职场文书
68句权威创业名言
2019/08/26 职场文书
Apache SkyWalking 监控 MySQL Server 实战解析
2022/09/23 Servers
源码安装apache脚本部署过程详解
2022/09/23 Servers