在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使用mailbox打印电子邮件的方法
Apr 30 Python
python append、extend与insert的区别
Oct 13 Python
python3 requests中使用ip代理池随机生成ip的实例
May 07 Python
对Python实现简单的API接口实例讲解
Dec 10 Python
python抓取网页内容并进行语音播报的方法
Dec 24 Python
Python玩转PDF的各种骚操作
May 06 Python
python cv2在验证码识别中应用实例解析
Dec 25 Python
python 输出列表元素实例(以空格/逗号为分隔符)
Dec 25 Python
PyTorch里面的torch.nn.Parameter()详解
Jan 03 Python
Python logging模块写入中文出现乱码
May 21 Python
Python同时处理多个异常的方法
Jul 28 Python
Python Charles抓包配置实现流程图解
Sep 29 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
实现WordPress主题侧边栏切换功能的PHP脚本详解
2015/12/14 PHP
最新最全PHP生成制作验证码代码详解(推荐)
2016/06/12 PHP
Laravel框架自定义验证过程实例分析
2019/02/01 PHP
PHP生成zip压缩包的常用方法示例
2019/08/22 PHP
PHP如何使用cURL实现Get和Post请求
2020/07/11 PHP
Jquery弹出窗口插件 LeanModal的使用方法
2012/03/10 Javascript
基于jquery的多功能软键盘插件
2012/07/25 Javascript
基于JavaScript自定义构造函数的详解说明
2013/04/24 Javascript
面向对象继承实例(a如何继承b问题)(自写)
2013/07/01 Javascript
jquery实现Ctrl+Enter提交表单的方法
2015/07/21 Javascript
js+css实现select的美化效果
2016/03/24 Javascript
JavaScript程序中实现继承特性的方式总结
2016/06/24 Javascript
JavaScript简单生成 N~M 之间随机数的方法
2017/01/13 Javascript
js实现仿购物车加减效果
2017/03/01 Javascript
bootstrap实现动态进度条效果
2017/03/08 Javascript
详解JS数组Reduce()方法详解及高级技巧
2017/08/18 Javascript
js实现九宫格抽奖
2020/03/19 Javascript
关于javascript中的promise的用法和注意事项(推荐)
2021/01/15 Javascript
[02:49]2018DOTA2亚洲邀请赛主赛事决赛日战况回顾 Mineski鏖战5局夺得辉耀
2018/04/10 DOTA
python通过cookie模拟已登录状态的初步研究
2016/11/09 Python
Flask框架的学习指南之开发环境搭建
2016/11/20 Python
Python模糊查询本地文件夹去除文件后缀的实例(7行代码)
2017/11/09 Python
python爬虫获取多页天涯帖子
2018/02/23 Python
python自动识别文本编码格式代码
2019/12/26 Python
CSS3 完美实现圆角效果
2009/07/13 HTML / CSS
基于HTML5陀螺仪实现ofo首页眼睛移动效果的示例
2017/07/31 HTML / CSS
科颜氏印度官网:Kiehl’s印度
2021/02/20 全球购物
vue路由实现登录拦截
2021/03/24 Vue.js
班组长安全职责
2014/01/05 职场文书
优秀教师的感人事迹
2014/02/04 职场文书
励志演讲稿3分钟
2014/08/21 职场文书
学习考察心得体会
2014/09/04 职场文书
新闻发布会活动策划方案
2014/09/15 职场文书
三好学生主要事迹怎么写
2015/11/03 职场文书
Python Django模型详解
2021/10/05 Python
Redis过期数据是否会被立马删除
2022/07/23 Redis