__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. 寒假作业pta2

    7-1 币值转换 (20 分) 输入一个整数(位数不超过9位)代表一个人民币值(单位为元),请转换成财务要求的大写中文格式.如23108元,转换后变成"贰万叁仟壹百零捌"元.为了简 ...

  2. Google - Reconstruct To Chain

    /* 4. 给你一串input,比如: A -> B B -> C X -> Y Z -> X . . . 然后让你设计一个data structure来存这些关系,最后读完了 ...

  3. mvc项目用log4net 记录错误日志

    1.  首先下载lognet 下载地址 http://logging.apache.org/log4net/download_log4net.cgi 2.找到bin文件中的net文件夹  之后看你电脑 ...

  4. php输出数据到csv文件

    function export() { $fileName = date('Y-m-d').uniqid().'.csv'; set_time_limit(0); ini_set('memory_li ...

  5. spring IOC 和AOP 方面

    spring 的2大核心 是Ioc 和 aop  spring的依赖注入:在程序运行期间,由外部容器动态的将依赖对象注入到组件中  IOC: 实例化spring容器的二种方法 第一种:在类路径下寻找配 ...

  6. java工程师-面试知识点总结

    目录(转载) [x] 一.Java基础(语言.集合框架.OOP.设计模式等) [x] 二.Java高级(JavaEE.框架.服务器.工具等) [x] 三.多线程和并发 [x] 四.Java虚拟机 [x ...

  7. .NET 定时执行任务解决方案(Timer & Quartz.Net)

    共有两种方法: 一.使用Timer global.asax <%@ Application Language="C#" %> <%@ import Namespa ...

  8. phpize是什么

    安装php(fastcgi模式)的时候,常常有这样一句命令:/usr/local/webserver/php/bin/phpize一.phpize是干嘛的?phpize是什么东西呢?php官方的说明: ...

  9. 阿里四不像Fourinone

    阿里四不像——分布式核心技术框架 Fourinone https://blog.csdn.net/shero_zsmj/article/details/52277194

  10. iterator简单描述

    Item 26. Prefer iterator to const iterator, reverse_iterator, and const_reverse_iterator. 上面一段话,是< ...