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解析发往本机的数据包示例 (解析数据包)
Jan 16 Python
python网页请求urllib2模块简单封装代码
Feb 07 Python
Python 冒泡,选择,插入排序使用实例
Feb 05 Python
Python的Django框架中的URL配置与松耦合
Jul 15 Python
Python3调用百度AI识别图片中的文字功能示例【测试可用】
Mar 13 Python
python中的print()输出
Apr 12 Python
PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
Jun 17 Python
详解Python 调用C# dll库最简方法
Jun 20 Python
python 用struct模块解决黏包问题
Nov 07 Python
python爬虫爬取图片的简单代码
Jan 18 Python
字典算法实现及操作 --python(实用)
Mar 31 Python
Pygame Time时间控制的具体使用详解
Nov 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/03/06 PHP
PHP并发多进程处理利器Gearman使用介绍
2016/05/16 PHP
在模板页面的js使用办法
2010/04/01 Javascript
jquery 操作两个select实现值之间的互相传递
2014/03/07 Javascript
浅谈javascript中for in 和 for each in的区别
2015/04/23 Javascript
JS实现文字掉落效果的方法
2015/05/06 Javascript
jQuery+JSON实现AJAX二级联动实例分析
2015/12/18 Javascript
JavaScript几种数组去掉重复值的方法推荐
2016/04/12 Javascript
分享12个非常实用的JavaScript小技巧
2016/05/11 Javascript
AngularJS基础 ng-disabled 指令详解及简单示例
2016/08/01 Javascript
很棒的一组js图片轮播特效
2017/01/12 Javascript
基于JavaScript实现的折半查找算法示例
2017/04/14 Javascript
基于ES6 Array.of的用法(实例讲解)
2017/09/05 Javascript
什么是Vue.js框架 为什么选择它?
2017/10/17 Javascript
Angular实现点击按钮控制隐藏和显示功能示例
2017/12/29 Javascript
vue通过点击事件读取音频文件的方法
2018/05/30 Javascript
[03:26]回顾2015国际邀请赛中国区预选赛
2015/06/09 DOTA
[01:14:31]Secret vs VG 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
Python实现截屏的函数
2015/07/25 Python
Python中标准模块importlib详解
2017/04/16 Python
Python中单、双下划线的区别总结
2017/12/01 Python
使用pandas读取csv文件的指定列方法
2018/04/21 Python
django admin 后台实现三级联动的示例代码
2018/06/22 Python
Django 路由系统URLconf的使用
2018/10/11 Python
Python整数对象实现原理详解
2019/07/01 Python
使用Python实现牛顿法求极值
2020/02/10 Python
使用wxpy实现自动发送微信消息功能
2020/02/28 Python
使用keras框架cnn+ctc_loss识别不定长字符图片操作
2020/06/29 Python
css3.0 图形构成实例练习二
2013/03/19 HTML / CSS
人事主管的岗位职责
2013/11/16 职场文书
咖啡厅创业计划书范本
2014/01/22 职场文书
出纳员岗位责任制
2014/02/11 职场文书
《绝招》教学反思
2016/02/20 职场文书
详解mysql三值逻辑与NULL
2021/05/19 MySQL
分享几个简单MySQL优化小妙招
2022/03/31 MySQL
电脑只能进入安全模式无法正常启动的解决办法
2022/04/08 数码科技