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中random模块用法实例分析
May 19 Python
Windows下Eclipse+PyDev配置Python+PyQt4开发环境
May 17 Python
Python的Django框架中forms表单类的使用方法详解
Jun 21 Python
python字符串str和字节数组相互转化方法
Mar 18 Python
python 性能优化方法小结
Mar 31 Python
Python中使用支持向量机(SVM)算法
Dec 26 Python
Python安装pycurl失败的解决方法
Oct 15 Python
PyTorch中Tensor的维度变换实现
Aug 18 Python
TensorBoard 计算图的可视化实现
Feb 15 Python
python实现吃苹果小游戏
Mar 21 Python
详解anaconda离线安装pytorchGPU版
Sep 08 Python
关于python中模块和重载的问题
Nov 02 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面向对象——访问修饰符介绍
2012/11/08 PHP
php删除文本文件中重复行的方法
2015/04/28 PHP
用dtree实现树形菜单 dtree使用说明
2011/10/17 Javascript
js正则表达式验证邮件地址
2015/11/12 Javascript
微信小程序使用第三方库Underscore.js步骤详解
2016/09/27 Javascript
connection reset by peer问题总结及解决方案
2016/10/21 Javascript
浅谈JS读取DOM对象(标签)的自定义属性
2016/11/21 Javascript
12 款 JS 代码测试必备工具(翻译)
2016/12/13 Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
2017/03/25 Javascript
Vue异步组件使用详解
2017/04/08 Javascript
Vue.js 2.0和Cordova开发webApp环境搭建方法
2018/02/26 Javascript
微信小程序实现弹出菜单功能
2018/06/12 Javascript
vue中动态设置meta标签和title标签的方法
2018/07/11 Javascript
vuex + axios 做登录验证 并且保存登录状态的实例
2018/09/16 Javascript
详解vuex中action何时完成以及如何正确调用dispatch的思考
2019/01/21 Javascript
vue中在vuex的actions中请求数据实例
2019/11/08 Javascript
vue+element导航栏高亮显示的解决方式
2019/11/12 Javascript
Nodejs实现WebSocket代码实例
2020/05/19 NodeJs
JS实现炫酷轮播图
2020/11/15 Javascript
JavaScript 实现继承的几种方式
2021/02/19 Javascript
python多进程读图提取特征存npy
2019/05/21 Python
django foreignkey(外键)的实现
2019/07/29 Python
Django1.11自带分页器paginator的使用方法
2019/10/31 Python
解决Opencv+Python cv2.imshow闪退问题
2020/04/24 Python
Python 按比例获取样本数据或执行任务的实现代码
2020/12/03 Python
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
意大利体育用品网上商城:Nencini Sport
2016/08/18 全球购物
加大码胸罩、内裤和服装:Just My Size
2019/03/21 全球购物
意大利在线高尔夫商店:Online Golf
2021/03/09 全球购物
美德少年事迹材料1000字
2014/08/21 职场文书
2015年全国爱眼日活动小结
2015/02/27 职场文书
拿破仑传读书笔记
2015/07/01 职场文书
车辆安全隐患排查制度
2015/08/05 职场文书
创业计划书介绍
2019/04/24 职场文书
Nginx工作原理和优化总结。
2021/04/02 Servers
SQL Server 数据库实验课第五周——常用查询条件
2021/04/05 SQL Server