Python是一门动态语言,可以在运行过程中,修改实例的属性和增删方法。任何实例都包含一个字典__dict__,该字典保存了实例所有的属性和方法。Python也通过这个字典可以将任意属性绑定到实例上。

有时候在实例的生命周期中处于安全等考虑只能操作固定的属性,不想增加属性,可以通过__slots__来就可以定义一个集合,只有在这个集合中的属性才能被操作。

__slots__ 是一个类的属性,有三个功能:

  1. 实例不能访问或添加__slots__之外的属性
  2. 实例没有__dict__方法
  3. 节省内存,实例保存属性的结构从字典变成列表

不使用__solt__

class A():

    t = 30
def __init__(self,x,y):
self.x = x
self.y = y def fun():
pass a = A(100,10)
print(a.__dict__)
print(a.x)
print(a.y)
print(a.t)
>>>
{'x': 100, 'y': 10}
100
10
30

特点:

  1. 可以通过a.__dict__ 输出实例所有属性
  2. 类变量不在a.__dict__管理的范围中

使用__slots__

不能动态添加属性

class A():
__slots__=('x', "y")
def __init__(self,x,y):
self.x = x
self.y = y
a = A(100,10)
print(a.x)
print(a.y)
>>>
100
10
a.z = 200
>>>
Traceback (most recent call last):
File "solt_demo.py", line 64, in <module>
a.z = 200
AttributeError: 'A' object has no attribute 'z'

实例的__dict__属性不存在

print(a.__dict__)
Traceback (most recent call last):
File "solt_demo.py", line 64, in <module>
print(a.__dict__)
AttributeError: 'A' object has no attribute '__dict__'

类属性不受影响

class A():
__slots__=('x', "y")
def __init__(self,x,y):
self.x = x
self.y = y A.new = 300
print(A.new)

子类不具有__slots__属性

父类中有__slots__,子类继承父类时子类不具有__slots__属性,可以操作实例的属性。

class A():
__slots__=('x', "y")
def __init__(self,x,y):
self.x = x
self.y = y class B(A):
pass b = B(33,44)
print(b.x)
print(b.y) b.z = 55
print(b.z)
print(b.__dict__)

更节省内存

不使用__slots__

from  memory_profiler import profile

class A():
def __init__(self,x,y):
self.x = x
self.y = y @profile
def main():
object_list = [A(100,20) for i in range(100000)] if __name__=='__main__':
main()
(python3.8) ➜  sublime python -m memory_profiler slots_demo.py
Filename: slots_demo.py Line # Mem usage Increment Occurrences Line Contents
=============================================================
9 13.8 MiB 13.8 MiB 1 @profile
10 def main():
11 30.0 MiB 16.2 MiB 100003 object_list = [A(100,20) for i in range(100000)]

使用__slots__

from  memory_profiler import profile

class A():
__slots__ = ("x", "y")
def __init__(self,x,y):
self.x = x
self.y = y @profile
def main():
object_list = [A(100,20) for i in range(100000)] if __name__=='__main__':
main()
(python3.8) ➜  sublime python -m memory_profiler slots_demo.py
Filename: slots_demo.py Line # Mem usage Increment Occurrences Line Contents
=============================================================
10 13.4 MiB 13.4 MiB 1 @profile
11 def main():
12 18.9 MiB 4.1 MiB 100003 object_list = [A(100,20) for i in range(100000)]

从结果来看不定义__slots__增加了16.2MB,定义__slots__增加了4.1MB,所以有理由相信有__slots__节省四分之三的内存。

节省内存的原因:

普通类使用字典保存所有属性,定义了__slots__之后使用列表保存所有属性,减少了内存的使用(因为属性个数固定,所有可以使用有序数据的列表,列表相比字典减少了内存消耗)

注意:

但是节省只在创建大量实例时才能体现。

总结

定义__slots__属性之后的特点如下:

  1. 实例的__dict__属性不存在,节省一定内存
  2. 不可以给实例动态绑定属性,但类的属性不受影响
  3. 子类继承有__solts__的父类时,不拥有__solts__,也就是子类不受限制
  4. 节省内存

参考:

https://blog.csdn.net/sxingming/article/details/52892640

Python中节省内存的方法之一:__slots__属性的更多相关文章

  1. PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。

    PySpark 的背后原理 Spark主要是由Scala语言开发,为了方便和其他系统集成而不引入scala相关依赖,部分实现使用Java语言开发,例如External Shuffle Service等 ...

  2. Python 中的内存管理

    Python 中一切皆对象,这些对象的内存都是在运行时动态地在堆中进行分配的,就连 Python 虚拟机使用的栈也是在堆上模拟的.既然一切皆对象,那么在 Python 程序运行过程中对象的创建和释放就 ...

  3. python中List的sort方法的用法

    python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. 关键字: python列表排序 python字典排序 sorted List的元素可以是各种东 ...

  4. 【转】python中List的sort方法(或者sorted内建函数)的用法

    原始出处:http://gaopenghigh.iteye.com/blog/1483864 python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. ...

  5. 【转】关于python中re模块split方法的使用

    注:最近在研究文本处理,需要用到正则切割文本,所以收索到了这篇文章,很有用,谢谢原作者. 原址:http://blog.sciencenet.cn/blog-314114-775285.html 关于 ...

  6. 查看python中模块的所有方法

    查看python中模块的所有方法     安装的python模块,现将查看方法总结如下 一.CMD命令行下使用pydoc命令 在命令行下运行$ pydoc modules即可查看 二.在python交 ...

  7. python中requests库使用方法详解

    目录 python中requests库使用方法详解 官方文档 什么是Requests 安装Requests库 基本的GET请求 带参数的GET请求 解析json 添加headers 基本POST请求 ...

  8. 全面了解python中的类,对象,方法,属性

    全面了解python中的类,对象,方法,属性 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...

  9. python中列表元素连接方法join用法实例

    python中列表元素连接方法join用法实例 这篇文章主要介绍了python中列表元素连接方法join用法,实例分析了Python中join方法的使用技巧,非常具有实用价值,分享给大家供大家参考. ...

  10. python 中去除空格的方法

    python 中去除空格的方法: def trim(s): l=[] for i in s: if i!=' ': l.append(i) return ''.join(l) 其中可以使用下面的 '' ...

随机推荐

  1. el-table 多表格弹窗嵌套数据显示异常错乱问题

    1.业务背景 使用vue+element开发报表功能时,需要列表上某列的超链接按钮弹窗展示,在弹窗的el-table列表某列中再次使用超链接按钮点开弹窗,以此类推多表格弹窗嵌套,本文以弹窗两次为例 最 ...

  2. 大白话说Python+Flask入门(三)

    写在前面 今天状态很不好,我发现学这部分知识的时候,会出现溜号或者注意力无法集中的情况. 我能想到的是,大概率是这部分知识,应该是超出了我现在的水平了,也就是说我存在知识断层了,整体感觉真的是一知半解 ...

  3. [ABC263E] Sugoroku 3

    Problem Statement There are $N$ squares called Square $1$ though Square $N$. You start on Square $1$ ...

  4. SpringBoot测试用例的一些小技巧~

    场景一:不想因为测试而对数据库产生脏数据 @Test public void testInsert() { User user = new User(); user.setUsername(" ...

  5. CH395实现主动ping对端功能(代码及说明)

    目录 1.PING原理 1.1简介 1.2协议 1.3通信流程 2.代码解释 3.工程链接 PING原理 1.简介 PING是基于ICMP(Internet Control Message Proto ...

  6. JXNU acm选拔赛 最小的数

    最小的数 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submissi ...

  7. 开源.NetCore通用工具库Xmtool使用连载 - 图像处理篇

    [Github源码] <上一篇> 介绍了Xmtool工具库中的扩展动态对象,今天我们继续为大家介绍其中的图像处理类库. 在我们的软件系统中,经常需要对图片进行各种各样的处理:例如最常见的头 ...

  8. 封装Detours用于Python中x64函数hook

    Detours 代码仓库: https://github.com/microsoft/Detours x64写一个任意地址hook要比x86麻烦的多,所以这里直接封装框架来用于x64的hook. De ...

  9. 由浅入深理解C#中的事件

    目录 本文较长,给大家提供了目录,可以直接看自己感兴趣的部分. 前言 有关事件的概念 示例 ​ 简单示例 ​ 标准 .NET 事件模式 ​ 使用泛型版本的标准 .NET 事件模式 ​ 补充 总结 参考 ...

  10. Ribbon:Spring Cloud负载均衡与服务调用组件

    Ribbon:Spring Cloud负载均衡与服务调用组件 问题总结 负载均衡? Ribbon实现服务调用? Ribbon实现负载均衡? 切换负载均衡策略? 定制负载均衡策略? 问题答案 负载均衡 ...