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的Flask框架中使用模版的入门教程
Apr 20 Python
Python中有趣在__call__函数
Jun 21 Python
用matplotlib画等高线图详解
Dec 14 Python
Python with语句上下文管理器两种实现方法分析
Feb 09 Python
Django 视图层(view)的使用
Nov 09 Python
如何在django里上传csv文件并进行入库处理的方法
Jan 02 Python
解决Python找不到ssl模块问题 No module named _ssl的方法
Apr 29 Python
Python代码实现http/https代理服务器的脚本
Aug 12 Python
numpy 声明空数组详解
Dec 05 Python
pytorch标签转onehot形式实例
Jan 02 Python
python3让print输出不换行的方法
Aug 24 Python
Python中zipfile压缩包模块的使用
May 14 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内核探索:变量概述
2014/01/30 PHP
PHP多线程之内部多线程实例分析
2015/03/09 PHP
php实现基于pdo的事务处理方法示例
2017/07/21 PHP
PHP 实现手机端APP支付宝支付功能
2018/06/07 PHP
PHP使用 Pear 进行安装和卸载包的方法详解
2019/07/08 PHP
javascript中callee与caller的用法和应用场景
2010/12/08 Javascript
JavaScript数据类型检测代码分享
2015/01/26 Javascript
javascript中加var和不加var的区别 你真的懂吗
2016/01/06 Javascript
详解nodeJS之二进制buffer对象
2017/06/03 NodeJs
Bootstrap4如何定制自己的颜色和风格
2018/02/26 Javascript
微信小程序使用template标签实现五星评分功能
2018/11/03 Javascript
vue中eslintrc.js配置最详细介绍
2018/12/21 Javascript
vue-cli项目使用mock数据的方法(借助express)
2019/04/15 Javascript
vue中格式化时间过滤器代码实例
2019/04/17 Javascript
vue权限问题的完美解决方案
2019/05/08 Javascript
react实现antd线上主题动态切换功能
2019/08/12 Javascript
使用webpack/gulp构建TypeScript项目的方法示例
2019/12/18 Javascript
uni-app 支持多端第三方地图定位的方法
2020/01/03 Javascript
使用 Opentype.js 生成字体子集的实例代码详解
2020/05/25 Javascript
[01:22]DOTA2神秘商店携大量周边降临完美大师赛
2017/11/07 DOTA
python解析xml模块封装代码
2014/02/07 Python
浅析python 内置字符串处理函数的使用方法
2014/06/11 Python
python实现ipsec开权限实例
2014/11/11 Python
Python关于反射的实例代码分享
2020/02/20 Python
Python selenium 加载并保存QQ群成员,去除其群主、管理员信息的示例代码
2020/05/28 Python
如何在Python对Excel进行读取
2020/06/04 Python
mac安装python3后使用pip和pip3的区别说明
2020/09/01 Python
什么是ESB?请介绍一下ESB?
2015/05/27 面试题
会计岗位职责
2013/11/08 职场文书
经济学博士求职自荐信范文
2013/11/23 职场文书
村党支部书记承诺书
2014/05/29 职场文书
计算机专业毕业生自荐书
2014/06/02 职场文书
付款委托书范本
2014/10/05 职场文书
大学生团日活动总结
2015/05/06 职场文书
python爬虫--selenium模块
2021/03/31 Python
InterProcessMutex实现zookeeper分布式锁原理
2022/03/21 Java/Android