在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 实现堆排序算法代码
Jun 05 Python
Python 爬虫模拟登陆知乎
Sep 23 Python
Scrapy框架CrawlSpiders的介绍以及使用详解
Nov 29 Python
Numpy 将二维图像矩阵转换为一维向量的方法
Jun 05 Python
Python图像处理之简单画板实现方法示例
Aug 30 Python
浅谈Python编程中3个常用的数据结构和算法
Apr 30 Python
Python文件操作模拟用户登陆代码实例
Jun 09 Python
Python 添加文件注释和函数注释操作
Aug 09 Python
利用Python的folium包绘制城市道路图的实现示例
Aug 24 Python
用python对oracle进行简单性能测试
Dec 05 Python
详解如何用Python实现感知器算法
Jun 18 Python
详解python的异常捕获
Mar 03 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
Thinkphp微信公众号支付接口
2016/08/04 PHP
thinkPHP事务操作简单案例分析
2019/10/17 PHP
PHP终止脚本运行三种实现方法详解
2020/09/01 PHP
JavaScript和ActionScript的交互实现代码
2010/08/01 Javascript
clipboard.js无需Flash无需依赖任何JS库实现文本复制与剪切
2015/10/10 Javascript
Javascript数组Array方法解读
2016/03/13 Javascript
bootstrap学习使用(导航条、下拉菜单、轮播、栅格布局等)
2016/12/01 Javascript
JS使用tofixed与round处理数据四舍五入的区别
2017/10/25 Javascript
vue单页应用加百度统计代码(亲测有效)
2018/01/31 Javascript
详解如何解决vue开发请求数据跨域的问题(基于浏览器的配置解决)
2018/11/12 Javascript
jquery实现直播弹幕效果
2019/11/28 jQuery
JS实现水平移动与垂直移动动画
2019/12/19 Javascript
JS严格模式原理与用法实例分析
2020/04/27 Javascript
[00:52]DOTA2齐天大圣预告片
2016/08/13 DOTA
Python实现的快速排序算法详解
2017/08/01 Python
简单了解Python中的几种函数
2017/11/03 Python
django admin添加数据自动记录user到表中的实现方法
2018/01/05 Python
对python中数组的del,remove,pop区别详解
2018/11/07 Python
Python实现蒙特卡洛算法小实验过程详解
2019/07/12 Python
Python日志syslog使用原理详解
2020/02/18 Python
Django之全局使用request.user.username的实例详解
2020/05/14 Python
Python如何使用PIL Image制作GIF图片
2020/05/16 Python
利用CSS3的flexbox实现水平垂直居中与三列等高布局
2016/09/12 HTML / CSS
医疗保健专业人士购物网站:Scrubs & Beyond
2017/02/08 全球购物
承认错误的检讨书
2014/01/30 职场文书
少先队学雷锋活动月总结
2014/03/09 职场文书
元旦促销方案
2014/03/15 职场文书
机关保密承诺书
2014/06/03 职场文书
市政工程技术专业自荐书
2014/07/06 职场文书
县委务虚会发言材料
2014/10/20 职场文书
2015年先进个人自荐书
2015/03/24 职场文书
李强感恩观后感
2015/06/17 职场文书
小学校长开学致辞
2015/07/29 职场文书
高中班主任工作总结(范文)
2019/08/20 职场文书
《天净沙·秋思》教学反思三篇
2019/11/02 职场文书
python第三方网页解析器 lxml 扩展库与 xpath 的使用方法
2021/04/06 Python