__slots__作用

__slots__有一个作用是:限制类实例绑定的属性,但是它有一个更重要的作用就是节省内存,当然更适用于数据量大的情况(万量级以上)。

__slots__节省内存的原理

class Measurement:
def __init__(self, x, y, value):
self.x = x
self.y = y
self.val = value m1 = Measurement(1, 2, "Happy")
m2 = Measurement(7, 10, "Crazy")
m2.other = True

其实,对类的变量值进行初始化,底层是通过一个指针指向__dict__(里面包含潜在的字段名和字段值)。举个例子,上面的程序底层实现过程如下:

我们也可以通过程序查看这一底层形式:
```
print(m1.__dict__) # {'x': 1, 'y': 2, 'val': 'Happy'}
print(m2.__dict__) # {'x': 7, 'y': 10, 'other': True, 'val': 'Crazy'}
```
这就是python自定义变量底层的一个基本实现。通过对这一底层理解,我们就会知道,如果我们的实例有数百万个,那么底层会有相应数百万个字典拥有相同的key值(知识value值不同),这时非常耗内存的,这时候__slots__就发挥它的作用了。

通过__slots__,我们可以稍微调整一下类,以改变类中字段的存储方式,废弃原来那种耗费内存的1对1重复的字典分配方式。具体如下:

class Measurement:
__slots__ = ['x', 'y', 'val'] def __init__(self, x, y, value):
self.x = x
self.y = y
self.val = value

这样我们底层的实现就会变为如下方式:

我们可以看出,现在字段名是与Measurement类这个类型相关联,而不是原来的与相应的实例1对1的关联。而字段值与原来的方式无差别,因为毕竟各个实例的字段名一样,可以统一存放,而字段值并不都是一样,当然对于字段值也一样的我们也统一存储(因为底层字典都是与类这个类型关联,而不是与每个实例的__dict__关联)。但对于数据量庞大的情况(数百万级以上),能够非常显著的节省内存空间(25.5GB -> 16.2GB)。

以上就是__slots__能够节省内存的原理,主要还是要搞清楚python的类变量初始化的底层操作是通过字典存储后相关联这一方式进行的,__slots__只是改变了字典key,value与实例相关联的方式,可以总结如下:

  • 默认变量实例化方法:底层实例和字典是一对一的关系

  • 加入__slots__后:底层实例和字典是多对一的关系(重复的部分)。

使用__slots__节省python内存技巧的更多相关文章

  1. 填坑总结:python内存泄漏排查小技巧

    摘要:最近服务遇到了内存泄漏问题,运维同学紧急呼叫解决,于是在解决问题之余也系统记录了下内存泄漏问题的常见解决思路. 本文分享自华为云社区<python内存泄漏排查小技巧>,作者:luti ...

  2. Python内存优化

    实际项目中,pythoner更加关注的是Python的性能问题,之前也写过一篇文章<Python性能优化>介绍Python性能优化的一些方法.而本文,关注的是Python的内存优化,一般说 ...

  3. Python内存优化:Profile,slots,compact dict

    实际项目中,pythoner更加关注的是Python的性能问题,之前也写过一篇文章<Python性能优化>介绍Python性能优化的一些方法.而本文,关注的是Python的内存优化,一般说 ...

  4. Python内存管理机制及优化简析(转载)

    from:http://kkpattern.github.io/2015/06/20/python-memory-optimization-zh.html 准备工作 为了方便解释Python的内存管理 ...

  5. 记一次调试python内存泄露的问题

    转载:http://www.jianshu.com/p/2d06a1a01cc3 这两天由于公司需要, 自己编写了一个用于接收dicom文件(医学图像文件)的server. 经过各种coding-de ...

  6. Python内存分配器(如何产生一个对象的过程)

    目录 内存分配器 Python分配器分层 第零层--通用的基础分配器 第一层--低级内存分配器 内存结构 arena pool new arena usable_arenas和unused_arena ...

  7. 【python测试开发栈】—python内存管理机制(二)—垃圾回收

    在上一篇文章中(python 内存管理机制-引用计数)中,我们介绍了python内存管理机制中的引用计数,python正是通过它来有效的管理内存.今天来介绍python的垃圾回收,其主要策略是引用计数 ...

  8. python实用技巧之任务切分

    Python 大任务切分小任务 今天来说说,Python中的任务切分.以爬虫为例,从一个存 url 的 txt 文件中,读取其内容,我们会获取一个 url 列表.我们把这一个 url 列表称为大任务. ...

  9. python内存管理(通俗易懂,详细可靠)

    python内存管理 python3.6.9 内存管理的官方文档 https://docs.python.org/zh-cn/3.6/c-api/memory.html 一.变量存哪了? x = 10 ...

随机推荐

  1. python select解析 socket高效通信服务器 自己写的socketserver

    import select import socket import queue server = socket.socket()#创建服务器端 server.bind(('localhost',99 ...

  2. ios-上传图片到后台

    做第一个项目时,有个版块的个人信息的编辑涉及到头像修改,老大说项目里有通用的代码,让我自己去找.总算找到,搞了许久才弄好,看来理解能力还需要提高啊!! #pragma mark- 修改头像上传后保存 ...

  3. java中的可释放资源定义,类似c#中的using

    public static class FileDuplicator implements AutoCloseable { Scanner in = null; PrintWriter out = n ...

  4. 建筑的永恒之道 (C·亚历山大 著)

    永恒之道 建筑或城市只有踏上了永恒之道,才会生机勃勃. 第1章 永恒之道 它是一个唯有我们自己才能带秩序的过程,它不可能被求取,但只要我们顺应它,它便会自然而然地出现. 质 为了探求永恒之道,我们首先 ...

  5. redis 4.x 安装哨兵模式 sentinel

    1.下载 http://download.redis.io/releases/redis-4.0.11.tar.gz 2.解压 tar zxvf redis-4.0.11.tar.gz 3.安装 cd ...

  6. threading模块小结

    这篇文章是别人文章的一个观后小结,不是什么原创. 首先第一个例子: import threading import time def worker():     print "worker& ...

  7. 当VUE 遇到微信js api

    先哭一会儿... history hash 1.如果使用history 方式,需要使用window.localtion.href="路径" 2.然后使用this.$router.p ...

  8. MySql开启远程账户登陆总结

    1.更改 "mysql" 数据库里的 "user" 表里的 "host" 项,从"127.0.0.1"改成"% ...

  9. denyhosts、中文文档乱码、端口占用查询

    1.安装 denyhosts, 设置 hosts.allow ,系统自动将攻击的ip 添加如 hosts.deny2.打开中文文档乱码, 将文档下载到windows, 通过富文本编辑器查看文档编码3. ...

  10. Solr——配置IK分词器

    首先需要的准备好jdk1.8和tomcat8以及ik分词器(ik分词器是5.x的版本,和solr4.10搭配的版本不一样,虽然是5.x的版本但是也是能使用在solr7.2版本上的) 分享链接https ...