在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使用线程封装的一个简单定时器类实例
May 16 Python
Python实现常见的回文字符串算法
Nov 14 Python
python执行精确的小数计算方法
Jan 21 Python
python opencv摄像头的简单应用
Jun 06 Python
python实现五子棋小程序
Jun 18 Python
django表单的Widgets使用详解
Jul 22 Python
python制作朋友圈九宫格图片
Nov 03 Python
python识别验证码图片实例详解
Feb 17 Python
Python random库使用方法及异常处理方案
Mar 02 Python
Python爬虫实现自动登录、签到功能的代码
Aug 20 Python
python爬虫之爬取笔趣阁小说
Apr 22 Python
Python爬取英雄联盟MSI直播间弹幕并生成词云图
Jun 01 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
解析php 版获取重定向后的地址(代码)
2013/06/26 PHP
php删除数组元素示例分享
2014/02/17 PHP
thinkphp中memcache的用法实例
2014/11/29 PHP
PHP mysql事务问题实例分析
2016/01/18 PHP
php实现的一段简单概率相关代码
2016/05/30 PHP
JQuery自定义事件的应用 JQuery最佳实践
2010/08/01 Javascript
jquery仿京东导航/仿淘宝商城左侧分类导航下拉菜单效果
2013/04/24 Javascript
jquery 实现上下滚动效果示例代码
2013/08/09 Javascript
JS小功能(offsetLeft实现图片滚动效果)实例代码
2013/11/28 Javascript
使用javaScript动态加载Js文件和Css文件
2015/10/24 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
2017/06/28 Javascript
node.js 发布订阅模式的实例
2017/09/10 Javascript
JS Input里添加小图标的两种方法
2017/11/11 Javascript
Vue项目部署在Spring Boot出现页面空白问题的解决方案
2018/11/26 Javascript
JS实现从对象获取对象中单个键值的方法示例
2019/06/05 Javascript
React传值 组件传值 之间的关系详解
2019/08/26 Javascript
vue实现简单跑马灯效果
2020/05/25 Javascript
如何使用Flask-Migrate拓展数据库表结构
2019/07/24 Python
Pycharm和Idea支持的vim插件的方法
2020/02/21 Python
pycharm中导入模块错误时提示Try to run this command from the system terminal
2020/03/26 Python
Python logging模块进行封装实现原理解析
2020/08/07 Python
python GUI计算器的实现
2020/10/09 Python
pycharm Tab键设置成4个空格的操作
2021/02/26 Python
KOHLER科勒美国官网:国际著名卫浴橱柜领先品牌
2020/06/27 全球购物
杭州联环马网络笔试题面试题
2013/08/04 面试题
Linux操作面试题
2012/05/16 面试题
药学专业毕业生求职信
2013/10/20 职场文书
请假条格式范文
2014/04/10 职场文书
集中整治工作方案
2014/05/01 职场文书
室内设计专业自荐信
2014/05/31 职场文书
2015年宣传部部长竞选演讲稿
2014/11/28 职场文书
幼儿园个人总结
2015/02/28 职场文书
实施意见格式范本
2015/06/05 职场文书
PostgreSQL通过oracle_fdw访问Oracle数据的实现步骤
2021/05/21 PostgreSQL
Mysql中一千万条数据怎么快速查询
2021/12/06 MySQL
如何设置多台电脑共享打印机?多台电脑共享打印机的方法
2022/04/08 数码科技