简介
在廖雪峰的python网站上,他是这么说的
python是动态语言,它允许程序在执行过程中动态绑定属性或者方法(使用MethodTpye)。
某个实例在执行过程中绑定的属性跟方法,仅在该实例中有效,其他同类实例是没有的。
可以通过给class绑定属性/方法,来给所有实例绑定属性/方法:
Student.name = '' Student.set_score = set_score
而如果使用__slots__,它仅允许动态绑定()里面有的属性
例如,下面这样会报错
class Student(): __slots__ = ('name', 'age') S1 = Student() S1.name = 'Jack' # ok! S1.score = 123 # error!
但是我觉得很奇怪,仅有这一个作用吗?于是我再查了其他资料,发现这个函数可以很可观地节约内存,下面来一起看看详细的介绍吧。
__slots__允许我们声明并限定类成员,并拒绝类创建__dict__和__weakref__属性以节约内存空间。
Python是动态语言,对于普通的类,可以为类实例赋值任何属性,这些属性会存储在__dict__中:
>>> class Student(object): ... pass ... >>> Abey = Student() >>> Abey.name = 'Abey' >>> Abey.__dict__ {'name': 'Abey'}
这样的特性带来两个问题:
当然,__slots__就能解决这两个问题。通过__slots__属性限定类属性的创建:
>>> class Student(object): ... __slots__ = ('name', 'age') ... >>> Abey = Student() >>> Abey.name = 'Abey' >>> Abey.gender = 'Female' Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'Student' object has no attribute 'gender' >>> Abey.__dict__ Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'Student' object has no attribute '__dict__'
可以看到,在定义了__slots__变量后,Student类实例已经不能随意创建不在__slots__定义内的属性gender,同时实例中也不再有__dict__结构。
用法
继承树
__slots__在继承中有两种表现:
以下面的父类为例:
>>> class Student(object): ... __slots__ = ('name', 'age') ...
创建一个子类不声明__slots__,该类实例可以创建父类__slots__限定之外的属性gender:
>>> class SubStudent(Student): ... pass ... >>> Bob = SubStudent() >>> Bob.gender = 'Male' >>> Bob.__dict__ {'gender': 'Male'}
而创建一个声明__slots__的子类,该类属性则只能创建父类__slots__+自身__slots__限定的属性:
>>> class SubStudent2(Student): ... __slots__ = 'gender' ... >>> Cathy = SubStudent2() >>> Cathy.gender = 'Female' >>> Cathy.name = 'Cathy' >>> Cathy.teacher = 'Mrs. Wang' Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'SubStudent2' object has no attribute 'teacher'
注意:子类的__slots__本身已经继承自父类,无需重复声明父类已声明的属性。例如上例,重复声明会多占用内存空间:
>>> class SubStudent3(Student): ... __slots__ = ('name', 'age', 'gender') ... >>> from sys import getsizeof >>> getsizeof(Student()), getsizeof(SubStudent2()), getsizeof(SubStudent3()) (56, 64, 80)
性能对比
我们为什么要使用__slots__呢?
更快速地赋值属性
参考Stack Overflow回答中给出的数据:
import timeit class Foo(object): __slots__ = 'foo', class Bar(object): pass slotted = Foo() not_slotted = Bar() def get_set_delete_fn(obj): def get_set_delete(): obj.foo = 'foo' obj.foo del obj.foo return get_set_delete
得到测试结果为:
>>> min(timeit.repeat(get_set_delete_fn(slotted)))
0.2846834529991611
>>> min(timeit.repeat(get_set_delete_fn(not_slotted)))
0.3664822799983085
可以看到,在相同的环境(Ubuntu)下,slots为Python3.5带来了接近30%的赋值速度提升:
节约内存空间
>>> 0.3664822799983085 / 0.2846834529991611 1.2873325658284342
由于不使用__dict__存储对象的属性,__slots__在一些场景下能够节约极大的内存空间。具体数据可以查看参考中的回答链接,不赘述。
参考
[1] Usage of __slots__? , Aaron Hall, Stack Overflow
推荐阅读
[1] Data model , Python Document
[2] python __slots__ 使你的代码更加节省内存 , david_bj, 51CTO
[3] 使用__slots__ , 廖雪峰
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。
本文向大家介绍Python中的__SLOTS__属性使用示例,包括了Python中的__SLOTS__属性使用示例的使用技巧和注意事项,需要的朋友参考一下 看python社区大妈组织的内容里边有一篇讲python内存优化的,用到了__slots__。然后查了一下,总结一下。感觉非常有用 python类在进行实例化的时候,会有一个__dict__属性,里边有可用的实例属性名和值。声明__slots_
主要内容:1 ThreadPoolExecutor的概述,2 ThreadPoolExecutor的主要属性,2.1 ctl相关方法,2.2 线程池的状态,3 ThreadPoolExecutor的构造器,3.1. corePoolSize、workQueue,maximumPoolSize ,keepAliveTime,unit之间关系,3.2 ThreadFactory 线程工厂,3.3 workQueue任务队列,基于JDK1.8详细介绍了ThreadPoolExecutor线程池的基本属
介绍PS Vita的基本操作和灵活使用PS Vita的提示。 各部名称 可使用的媒体类型 充电 启动/关闭电源 触摸操作与感测器 基本操作 如何使用画面 启动/关闭应用程序 随意调整主画面 输入文字 与互联网连接 关闭声音 调整屏幕的亮度 拍摄画面截图 执行视听者限制 丢弃或转让PS Vita 主机时的注意事项
1.1. 学校专属的的在线教学平台 学校云是以云服务的方式提供给院校的在线教学平台和课程资源,帮助学校实现线上教学、混合式教学和移动学习,用信息化的手段帮助学校提高教学效率和教学质量。与中国大学MOOC在课程资源和教学过程上实现无缝衔接。 每个学校拥有独立的站点,专属的门户页面,所有的学生、教师、课程和教学过程数据均为私有,只有本校的师生可以访问。网易云底层架构保证平台的高可用、高并发和数据安全。
本文向大家介绍Python中的defaultdict与__missing__()使用介绍,包括了Python中的defaultdict与__missing__()使用介绍的使用技巧和注意事项,需要的朋友参考一下 前言 今天我们的主角是 defaultdict ,同时也会介绍一下模仿方法 __missing__() ,本文主要来源于网友博客,分享给有需要的人。下面话不多说了,来一起看看详细的介绍吧。
本文向大家介绍Python中psutil的介绍与用法,包括了Python中psutil的介绍与用法的使用技巧和注意事项,需要的朋友参考一下 psutil简介 psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。它主要用来做系统监控,性能分析,进程管理。它实现了同等命令行工具提供