在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 相关文章推荐
Python内建模块struct实例详解
Feb 02 Python
基于Python实现的微信好友数据分析
Feb 26 Python
PyCharm安装第三方库如Requests的图文教程
May 18 Python
Linux下Python安装完成后使用pip命令的详细教程
Nov 22 Python
使用 Python 玩转 GitHub 的贡献板(推荐)
Apr 04 Python
python logging日志模块原理及操作解析
Oct 12 Python
在Python中使用filter去除列表中值为假及空字符串的例子
Nov 18 Python
python 控制台单行刷新,多行刷新实例
Feb 19 Python
python爬虫可以爬什么
Jun 16 Python
使用AJAX和Django获取数据的方法实例
Oct 25 Python
教你用Python写一个植物大战僵尸小游戏
Apr 25 Python
浅谈python中的多态
Jun 15 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
Ajax PHP分页演示
2007/01/02 PHP
linux命令之调试工具strace的深入分析
2013/06/03 PHP
比较strtr, str_replace和preg_replace三个函数的效率
2013/06/26 PHP
解析wamp5下虚拟机配置文档
2013/06/27 PHP
php获取当前月与上个月月初及月末时间戳的方法
2016/12/05 PHP
PHP中递归的实现实例详解
2017/11/14 PHP
jQuery.clean使用方法及思路分析
2013/01/07 Javascript
js中同步与异步处理的方法和区别总结
2013/12/25 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
jQuery插件jRumble实现网页元素抖动
2015/06/05 Javascript
如何屏蔽防止别的网站嵌入框架代码
2015/08/24 Javascript
JavaScript判断图片是否已经加载完毕的方法汇总
2016/02/05 Javascript
深入理解jQuery layui分页控件的使用
2016/08/17 Javascript
bootstrap基础知识学习笔记
2016/11/02 Javascript
Vue.JS入门教程之事件监听
2016/12/01 Javascript
JS前端笔试题分析
2016/12/19 Javascript
Vue.js实现表格动态增加删除的方法(附源码下载)
2017/01/20 Javascript
Web开发中客户端的跳转与服务器端的跳转的区别
2017/03/05 Javascript
JS异步函数队列功能实例分析
2017/11/28 Javascript
jQuery中库的引用方法
2018/01/06 jQuery
vue环形进度条组件实例应用
2018/10/10 Javascript
mock.js模拟前后台交互
2019/07/25 Javascript
Python实现统计英文单词个数及字符串分割代码
2015/05/28 Python
常用python编程模板汇总
2016/02/12 Python
Python基于回溯法子集树模板解决取物搭配问题实例
2017/09/02 Python
Python运维之获取系统CPU信息的实现方法
2018/06/11 Python
jupyter notebook中新建cell的方法与快捷键操作
2020/04/22 Python
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
洛杉矶健身中心女性专用运动服饰品牌:Marika
2018/05/09 全球购物
服装创业计划书范文
2014/02/05 职场文书
索桥的故事教学反思
2014/02/06 职场文书
新法人代表任命书
2014/06/06 职场文书
社区六一儿童节活动总结
2015/02/11 职场文书
2016师德师风学习心得体会
2016/01/12 职场文书
电力安全学习心得体会
2016/01/18 职场文书
Python控制台输出俄罗斯方块移动和旋转功能
2021/04/18 Python