在Python中使用__slots__方法的详细教程


Posted in Python onApril 28, 2015

正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。先定义class:

>>> class Student(object):
...   pass
...

然后,尝试给实例绑定一个属性:

>>> s = Student()
>>> s.name = 'Michael' # 动态给实例绑定一个属性
>>> print s.name
Michael

还可以尝试给实例绑定一个方法:

>>> def set_age(self, age): # 定义一个函数作为实例方法
...   self.age = age
...
>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s, Student) # 给实例绑定一个方法
>>> s.set_age(25) # 调用实例方法
>>> s.age # 测试结果
25

但是,给一个实例绑定的方法,对另一个实例是不起作用的:

>>> s2 = Student() # 创建新的实例
>>> s2.set_age(25) # 尝试调用方法
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'set_age'

为了给所有实例都绑定方法,可以给class绑定方法:

>>> def set_score(self, score):
...   self.score = score
...
>>> Student.set_score = MethodType(set_score, None, Student)

给class绑定方法后,所有实例均可调用:

>>> s.set_score(100)
>>> s.score
100
>>> s2.set_score(99)
>>> s2.score
99

通常情况下,上面的set_score方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现。
使用__slots__

但是,如果我们想要限制class的属性怎么办?比如,只允许对Student实例添加name和age属性。

为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class能添加的属性:

>>> class Student(object):
...   __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
...

然后,我们试试:

>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name'
>>> s.age = 25 # 绑定属性'age'
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'

由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。

使用__slots__要注意,__slots__定义的属性仅对当前类起作用,对继承的子类是不起作用的:

>>> class GraduateStudent(Student):
...   pass
...
>>> g = GraduateStudent()
>>> g.score = 9999
Try

除非在子类中也定义__slots__,这样,子类允许定义的属性就是自身的__slots__加上父类的__slots__。

Python 相关文章推荐
windows系统中python使用rar命令压缩多个文件夹示例
May 06 Python
讲解Python中运算符使用时的优先级
May 14 Python
Django 多语言教程的实现(i18n)
Jul 07 Python
浅谈pytorch和Numpy的区别以及相互转换方法
Jul 26 Python
Python+OpenCV采集本地摄像头的视频
Apr 25 Python
numpy.random模块用法总结
May 27 Python
Django RBAC权限管理设计过程详解
Aug 06 Python
Django中自定义查询对象的具体使用
Oct 13 Python
Python 列表的清空方式
Jan 13 Python
Python如何将装饰器定义为类
Jul 30 Python
如何在scrapy中集成selenium爬取网页的方法
Nov 18 Python
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
Jun 05 Python
Python实现扫描局域网活动ip(扫描在线电脑)
Apr 28 #Python
python将文本转换成图片输出的方法
Apr 28 #Python
Python psutil模块简单使用实例
Apr 28 #Python
Python RuntimeError: thread.__init__() not called解决方法
Apr 28 #Python
Python标准库defaultdict模块使用示例
Apr 28 #Python
Python自动重试HTTP连接装饰器
Apr 28 #Python
Python2.6版本中实现字典推导 PEP 274(Dict Comprehensions)
Apr 28 #Python
You might like
改造一台复古桌面收音机
2021/03/02 无线电
php生成略缩图代码
2012/07/16 PHP
用Php编写注册后Email激活验证的实例代码
2013/03/11 PHP
php清空(删除)指定目录下的文件,不删除目录文件夹的实现代码
2014/09/04 PHP
zen_cart实现支付前生成订单的方法
2016/05/06 PHP
Js实现滚动变色的文字效果
2014/06/16 Javascript
常用的JavaScript WEB操作方法分享
2015/02/28 Javascript
javascript实现Table排序的方法
2015/05/15 Javascript
浅谈JavaScript中promise的使用
2017/01/11 Javascript
jQuery监听浏览器窗口大小的变化实例
2017/02/07 Javascript
js eval函数使用,js对象和字符串互转实例
2017/03/06 Javascript
nodejs入门教程六:express模块用法示例
2017/04/24 NodeJs
深入理解React Native原生模块与JS模块通信的几种方式
2017/07/24 Javascript
纯js实现画一棵树的示例
2017/09/05 Javascript
layui实现鼠标移动到单元格上显示数据的方法
2019/09/11 Javascript
Js参数RSA加密传输之jsencrypt.js的使用
2020/02/07 Javascript
vue-preview动态获取图片宽高并增加旋转功能的实现
2020/07/29 Javascript
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
python读取word文档的方法
2015/05/09 Python
window下eclipse安装python插件教程
2017/04/24 Python
python使用fork实现守护进程的方法
2017/11/16 Python
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
树莓派使用python-librtmp实现rtmp推流h264的方法
2019/07/22 Python
ipad上运行python的方法步骤
2019/10/12 Python
python GUI库图形界面开发之PyQt5 MDI(多文档窗口)QMidArea详细使用方法与实例
2020/03/05 Python
解决Keras 自定义层时遇到版本的问题
2020/06/16 Python
Oakley官网:运动太阳镜、雪镜和服装
2016/09/30 全球购物
意大利灯具购物网站:Lampade.it
2018/10/18 全球购物
英国领先的在线高尔夫商店:Scottsdale Golf
2019/08/26 全球购物
J2EE中的容器都包括哪些
2013/08/21 面试题
面试后的感谢信范文
2014/02/01 职场文书
厉行勤俭节约倡议书
2014/05/16 职场文书
优秀家长事迹材料
2014/05/17 职场文书
感恩老师演讲稿600字
2014/08/28 职场文书
2015年幼儿园学前班工作总结
2015/05/18 职场文书
2015年小学财务工作总结
2015/07/20 职场文书