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中文问题解决方法(总结了多位前人经验,初学者必看)
Mar 13 Python
Python实现截屏的函数
Jul 25 Python
python+django快速实现文件上传
Oct 24 Python
Python机器学习之K-Means聚类实现详解
Feb 22 Python
基于python实现百度翻译功能
May 09 Python
python保存字典和读取字典的实例代码
Jul 07 Python
Python之虚拟环境virtualenv,pipreqs生成项目依赖第三方包的方法
Jul 23 Python
python树的同构学习笔记
Sep 14 Python
Python collections中的双向队列deque简单介绍详解
Nov 04 Python
Python基于traceback模块获取异常信息
Jul 23 Python
Selenium alert 弹窗处理的示例代码
Aug 06 Python
详解python中的闭包
Sep 07 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支持页面回退的两种方法
2008/01/10 PHP
探讨php中header的用法详解
2013/06/07 PHP
php 在windows下配置虚拟目录的方法介绍
2013/06/26 PHP
php使用Image Magick将PDF文件转换为JPG文件的方法
2015/04/01 PHP
var与Javascript变量隐式声明
2009/09/17 Javascript
javascript中的缓动效果实现程序
2012/12/29 Javascript
JS中的substring和substr函数的区别说明
2013/05/07 Javascript
JS画线(实例代码)
2013/11/20 Javascript
中止javascript执行的方法
2014/02/14 Javascript
jQuery中width()方法用法实例
2014/12/24 Javascript
jQuery插件bxSlider实现响应式焦点图
2015/04/12 Javascript
js实现点击向下展开的下拉菜单效果代码
2015/09/01 Javascript
深入理解jquery中的each用法
2016/12/14 Javascript
jQueryUI 拖放排序遇到滚动条时有可能无法执行排序的小bug及解决方案
2016/12/19 Javascript
JS使用正则实现去掉字符串左右空格的方法
2016/12/27 Javascript
详解EasyUi控件中的Datagrid
2017/08/23 Javascript
angular中两种表单的区别(响应式和模板驱动表单)
2018/12/06 Javascript
JS左右无缝轮播功能完整实例
2019/05/16 Javascript
Vue指令之 v-cloak、v-text、v-html实例详解
2019/08/08 Javascript
微信小程序基于movable-view实现滑动删除效果
2020/01/08 Javascript
微信小程序聊天功能的示例代码
2020/01/13 Javascript
微信小程序图片自适应实现解析
2020/01/21 Javascript
分析python服务器拒绝服务攻击代码
2014/01/16 Python
Python中的anydbm模版和shelve模版使用指南
2015/07/09 Python
Python读写unicode文件的方法
2015/07/10 Python
Python argv用法详解
2016/01/08 Python
python 创建一个空dataframe 然后添加行数据的实例
2018/06/07 Python
浅析python3字符串格式化format()函数的简单用法
2018/12/07 Python
详解python 模拟豆瓣登录(豆瓣6.0)
2019/04/18 Python
基于python分析你的上网行为 看看你平时上网都在干嘛
2019/08/13 Python
美国最大的半成品净菜电商:Blue Apron(蓝围裙)
2018/04/27 全球购物
以下为Windows NT 下的32 位C++程序,请计算sizeof 的值
2016/12/07 面试题
市场开发计划书
2014/05/07 职场文书
教师党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
读《茶花女》有感:山茶花的盛开与凋零
2020/01/17 职场文书
Django与数据库交互的实现
2021/06/03 Python