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 linecache.getline()读取文件中特定一行的脚本
Sep 06 Python
Python随机生成彩票号码的方法
Mar 05 Python
Python如何实现文本转语音
Aug 08 Python
Python随机函数random()使用方法小结
Apr 29 Python
python 3.6.2 安装配置方法图文教程
Sep 18 Python
python openCV获取人脸部分并存储功能
Aug 28 Python
Python爬虫之urllib基础用法教程
Oct 12 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
Oct 30 Python
详解Python 最短匹配模式
Jul 29 Python
Django nginx配置实现过程详解
Sep 10 Python
Python中非常使用的6种基本变量的操作与技巧
Mar 22 Python
Python  序列化反序列化和异常处理的问题小结
Dec 24 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缓存类分享     php缓存机制
2014/01/22 PHP
Php中使用Select 查询语句的实例
2014/02/19 PHP
php获取textarea的值并处理回车换行的方法
2014/10/20 PHP
PHP XML和数组互相转换详解
2016/10/26 PHP
php 的多进程操作实践案例分析
2020/02/28 PHP
jQuery的实现原理的模拟代码 -1 核心部分
2010/08/01 Javascript
jquery ajax对特殊字符进行转义防止js注入使用示例
2013/11/21 Javascript
2014 HTML5/CSS3热门动画特效TOP10
2014/12/07 Javascript
深入理解jQuery中的事件冒泡
2016/05/24 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
2016/09/08 Javascript
ES6新增的math,Number方法
2017/08/06 Javascript
JS实现的数组去除重复数据算法小结
2017/11/17 Javascript
浅谈Webpack打包优化技巧
2018/06/12 Javascript
浅谈Angular7 项目开发总结
2018/12/19 Javascript
JavaScript ES2019中的8个新特性详解
2019/02/20 Javascript
JS前端广告拦截实现原理解析
2020/02/17 Javascript
vue在图片上传的时候压缩图片
2020/11/18 Vue.js
[38:23]完美世界DOTA2联赛循环赛 FTD vs PXG BO2第二场 11.01
2020/11/02 DOTA
Python基于QRCode实现生成二维码的方法【下载,安装,调用等】
2017/07/11 Python
在CentOS6上安装Python2.7的解决方法
2018/01/09 Python
python 自定义对象的打印方法
2019/01/12 Python
python实现最小二乘法线性拟合
2019/07/19 Python
python sqlite的Row对象操作示例
2019/09/11 Python
python3中使用__slots__限定实例属性操作分析
2020/02/14 Python
python如何求100以内的素数
2020/05/27 Python
pytorch查看模型weight与grad方式
2020/06/24 Python
Python如何实现自带HTTP文件传输服务
2020/07/08 Python
python 简单的调用有道翻译
2020/11/25 Python
HTML5网页录音和上传到服务器支持PC、Android,支持IOS微信功能
2019/04/26 HTML / CSS
HTML里显示pdf、word、xls、ppt的方法示例
2020/04/14 HTML / CSS
RentCars.com巴西:汽车租赁网站
2016/08/22 全球购物
德国家用电器购物网站:Premiumshop24
2019/08/22 全球购物
水利专业大学生职业生涯规划书范文
2014/09/17 职场文书
村当支部个人对照检查材料思想汇报
2014/10/06 职场文书
Redis主从配置和底层实现原理解析(实战记录)
2021/06/30 Redis
Spring Boot 的创建和运行示例代码详解
2022/07/23 Java/Android