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. 从混乱到优雅:基于DDD的六边形架构的代码翻新指南

    前言 趁着双十一备战封板,终于又有一些时间可以梳理一下最近的心得. 最近这半年跟同事讨论比较多的是分层架构,然后就会遇到两个触及灵魂的问题,一个是如何做好分层架构,二是DDD在架构层面该如何落地. 为 ...

  2. 牛客多校第二场 I.Penguins

    题意 两个企鹅,一个从地图的右下角走右上角,一个从另一个地图的左下角走到左上角,我们操控左边的企鹅,右边的企鹅与左边企鹅运动规则如下. 左边企鹅向左,右边企鹅向右 左边企鹅向右,右边企鹅向左 左边企鹅 ...

  3. Node01-简介与安装

    01. Node.js是什么? pNode.js是一个基于V8 JavaScript引擎的JavaScript运行时环境. 也就是说: Node.js基于V8引擎来执行JavaScript的代码. V ...

  4. 七天.NET 8操作SQLite入门到实战 - 第四天EasySQLite前后端项目框架搭建

    前言 今天的主要任务是快速下载并安装.NET 8 SDK,搭建EasySQLite的前后端框架. .NET 8 介绍 .NET 8 是 .NET 7 的后继版本. 它将作为长期支持 (LTS) 版本得 ...

  5. Hudi 在 vivo 湖仓一体的落地实践

    作者:vivo 互联网大数据团队 - Xu Yu 在增效降本的大背景下,vivo大数据基础团队引入Hudi组件为公司业务部门湖仓加速的场景进行赋能.主要应用在流批同源.实时链路优化及宽表拼接等业务场景 ...

  6. .NET周刊【12月第2期 2023-12-13】

    国内文章 用最清爽的方式开发dotNet https://www.cnblogs.com/ncellit/p/17881779.html 本文介绍了如何以清爽的方式开发dotNet应用,特别是简单的A ...

  7. 51Nod 1085 01背包

    01背包入门题,刚学完当写模板. 在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2--Wn(Wi为整数),与之相对应的价值为P1,P2--Pn(Pi为整数).求背包能够容纳的最大价 ...

  8. Shell下处理JSON数据工具向导

    目录 下载离线安装包 安装 源码包安装 选项及含义 JQ 程序代码演示在线平台 JQ 语法 基本过滤器 身份运算符 --- . 标识符-索引 --- .foo`, `.foo.bar 对象索引 --- ...

  9. influxdb 进行数据删除和修改

    本文为博主原创,转载请注明出处: 1.条件删除数据 InfluxDB 只支持基于时间的删除操作. 可以使用 DELETE 语句来删除指定时间范围内的数据.例如,以下的 SQL 语句将删除 measur ...

  10. Pikachu漏洞靶场 Burte Force(暴力破解)

    Burte Force(暴力破解) 文章目录 Burte Force(暴力破解) 概述 1.基于表单的暴力破解 2.验证码绕过(on server) 3.验证码绕过(on client) 4.toke ...