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操作数据库之sqlite3打开数据库、删除、修改示例
Mar 13 Python
Python实现遍历数据库并获取key的值
May 17 Python
Python实现telnet服务器的方法
Jul 10 Python
分享Pycharm中一些不为人知的技巧
Apr 03 Python
解决python3 pika之连接断开的问题
Dec 18 Python
Python爬虫实战之12306抢票开源
Jan 24 Python
Python基于Dlib的人脸识别系统的实现
Feb 26 Python
python数据类型可变不可变知识点总结
Mar 06 Python
keras topN显示,自编写代码案例
Jul 03 Python
Python 实现3种回归模型(Linear Regression,Lasso,Ridge)的示例
Oct 15 Python
python 如何读、写、解析CSV文件
Mar 03 Python
Django项目配置Memcached和Redis, 缓存选择哪个更有优势
Apr 06 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
mantis安装、配置和使用中的问题小结
2014/07/14 PHP
Yii2中datetime类的使用
2016/12/17 PHP
PHP解决中文乱码
2017/04/28 PHP
PHP接入微信H5支付的方法示例
2019/10/28 PHP
thinkphp5框架路由原理与用法详解
2020/02/11 PHP
jquery创建一个ajax关键词数据搜索实现思路
2013/02/26 Javascript
解析URI与URL之间的区别与联系
2013/11/22 Javascript
Javascript学习笔记之函数篇(五) : 构造函数
2014/11/23 Javascript
jQuery+CSS3文字跑马灯特效的简单实现
2016/06/25 Javascript
JS构造函数与原型prototype的区别介绍
2016/07/04 Javascript
EditPlus中的正则表达式 实战(2)
2016/12/15 Javascript
微信小程序 引用其他js文件实现代码
2017/02/22 Javascript
基于js中document.cookie全面解析
2017/09/14 Javascript
微信小程序实现人脸检测功能
2018/05/25 Javascript
vue插槽slot的理解和使用方法
2019/04/03 Javascript
通过jQuery学习js类型判断的技巧
2019/05/27 jQuery
js中let能否完全替代IIFE
2019/06/15 Javascript
JS实现iframe中子父页面跨域通讯的方法分析
2020/03/10 Javascript
详解vue高级特性
2020/06/09 Javascript
纯CSS3实现3D旋转书本效果
2016/03/21 HTML / CSS
预订从美国飞往印度的机票:MyTicketsToIndia
2017/05/19 全球购物
ManoMano英国:欧洲第一家专注于DIY和园艺市场的电商平台
2020/03/12 全球购物
Python里面如何拷贝一个对象
2014/02/17 面试题
业务主管岗位职责范本
2013/12/25 职场文书
打架检讨书800字
2014/01/10 职场文书
运动会广播稿500字
2014/01/28 职场文书
幼儿园户外活动总结
2014/07/04 职场文书
国家税务局领导班子对照检查材料思想汇报
2014/10/04 职场文书
2014年法制宣传日活动方案
2014/11/02 职场文书
2014年车间工作总结
2014/11/21 职场文书
武当山导游词
2015/02/03 职场文书
中标通知书格式
2015/04/17 职场文书
跳高加油稿
2015/07/21 职场文书
2015年财务人员个人工作总结
2015/07/27 职场文书
Python如何使用logging为Flask增加logid
2021/03/30 Python
MySQL分区以及建索引的方法总结
2022/04/13 MySQL