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 代码效率的方法
Jul 03 Python
Python验证码识别处理实例
Dec 28 Python
Python操作Access数据库基本步骤分析
Sep 19 Python
浅谈django model的get和filter方法的区别(必看篇)
May 23 Python
Python MD5加密实例详解
Aug 02 Python
python http接口自动化脚本详解
Jan 02 Python
如何利用Boost.Python实现Python C/C++混合编程详解
Nov 08 Python
Python实现使用request模块下载图片demo示例
May 24 Python
python机器学习库scikit-learn:SVR的基本应用
Jun 26 Python
浅析Python 中几种字符串格式化方法及其比较
Jul 02 Python
python代码如何实现余弦相似性计算
Feb 09 Python
python+requests实现接口测试的完整步骤
Oct 27 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
改德生G88 - 加装等响度低音提升电路
2021/03/02 无线电
PHP代码维护,重构变困难的4种原因分析
2016/01/25 PHP
PHP之认识(二)关于Traits的用法详解
2019/04/11 PHP
php use和include区别总结
2019/10/13 PHP
javascript最常用与实用的创建类的代码
2010/08/12 Javascript
jQuery UI Autocomplete 1.8.16 中文输入修正代码
2012/04/16 Javascript
拖动table标题实现改变td的大小(css+js代码)
2013/04/16 Javascript
jquery与prototype框架的详细对比
2013/11/21 Javascript
JavaScript代码应该放在HTML代码哪个位置比较好?
2014/10/16 Javascript
JavaScript判断是否为数组的3种方法及效率比较
2015/04/01 Javascript
javascript实现checkbox全选的代码
2015/04/30 Javascript
JavaScript数组迭代方法
2017/03/03 Javascript
Angular整合zTree的示例代码
2018/01/24 Javascript
clipboard在vue中的使用的方法示例
2018/10/19 Javascript
elementUI 设置input的只读或禁用的方法
2018/10/30 Javascript
vue路由--网站导航功能详解
2019/03/29 Javascript
VUE接入腾讯验证码功能(滑块验证)备忘
2019/05/07 Javascript
微信小程序12行js代码自己写个滑块功能(推荐)
2020/07/15 Javascript
基于elementUI竖向表格、和并列的案例
2020/10/26 Javascript
[01:20]PWL S2开团时刻第三期——团战可以输 蝙蝠必须死
2020/11/26 DOTA
Python使用functools模块中的partial函数生成偏函数
2016/07/02 Python
Python编程产生非均匀随机数的几种方法代码分享
2017/12/13 Python
Python中的pack和unpack的使用
2018/03/12 Python
Python中logging实例讲解
2019/01/17 Python
linux环境下Django的安装配置详解
2019/07/22 Python
Python全栈之列表数据类型详解
2019/10/01 Python
python实现字符串和数字拼接
2020/03/02 Python
自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码
2020/03/30 Python
python中翻译功能translate模块实现方法
2020/12/17 Python
css3类选择器之结合元素选择器和多类选择器用法
2017/03/09 HTML / CSS
使用PDF.JS插件在HTML中预览PDF文件的方法
2018/08/29 HTML / CSS
FC-Moto英国:欧洲最大的摩托车服装和头盔商店之一
2019/08/25 全球购物
Why we need EJB
2016/10/20 面试题
2015小学教师年度工作总结
2015/05/12 职场文书
听课评课活动心得体会
2016/01/15 职场文书
古诗文之爱国名句(77句)
2019/09/24 职场文书