在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 SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
May 06 Python
十个Python程序员易犯的错误
Dec 15 Python
Python 专题六 局部变量、全局变量global、导入模块变量
Mar 20 Python
python+selenium打印当前页面的titl和url方法
Jun 22 Python
PyQt QListWidget修改列表项item的行高方法
Jun 20 Python
python判断自身是否正在运行的方法
Aug 08 Python
使用python os模块复制文件到指定文件夹的方法
Aug 22 Python
tesserocr与pytesseract模块的使用方法解析
Aug 30 Python
Selenium及python实现滚动操作多种方法
Jul 21 Python
Python利用Pillow(PIL)库实现验证码图片的全过程
Oct 04 Python
Python中的min及返回最小值索引的操作
May 10 Python
python之np.argmax()及对axis=0或者1的理解
Jun 02 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数字运算验证码的实现代码
2015/07/30 PHP
PHP使用反射机制实现查找类和方法的所在位置
2016/04/22 PHP
PHP编写简单的App接口
2016/08/28 PHP
ThinkPHP简单使用memcache缓存的方法
2016/11/15 PHP
thinkphp框架使用JWTtoken的方法详解
2019/10/10 PHP
Laravel 解决composer相关操作提示php相关异常的问题
2019/10/23 PHP
json跟xml的对比分析
2008/06/10 Javascript
JS鼠标滑过图片时切换图片实现思路
2013/09/12 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
2014/06/05 Javascript
BootStrap实现带有增删改查功能的表格(DEMO详解)
2016/10/26 Javascript
值得学习的bootstrap fileinput文件上传工具
2016/11/08 Javascript
微信小程序 网络请求(GET请求)详解
2016/11/16 Javascript
老生常谈combobox和combotree模糊查询
2017/04/17 Javascript
vue-i18n结合Element-ui的配置方法
2019/05/20 Javascript
基于JS实现数字动态变化显示效果附源码
2019/07/18 Javascript
通过实例了解Javascript柯里化流程
2020/03/03 Javascript
微信小程序实现购物车小功能
2020/12/30 Javascript
Python生成器(Generator)详解
2015/04/13 Python
Python中Continue语句的用法的举例详解
2015/05/14 Python
Python手机号码归属地查询代码
2016/05/04 Python
78行Python代码实现现微信撤回消息功能
2018/07/26 Python
NumPy 基本切片和索引的具体使用方法
2019/04/24 Python
把vgg-face.mat权重迁移到pytorch模型示例
2019/12/27 Python
Python Spyder 调出缩进对齐线的操作
2021/02/26 Python
PatPat香港:婴童服饰和亲子全家装在线购物
2020/09/27 全球购物
热能动力工程毕业生自荐信
2013/11/07 职场文书
硕士研究生自我鉴定
2013/11/08 职场文书
优秀员工个人的自我评价
2013/11/29 职场文书
社区志愿者心得体会
2014/01/03 职场文书
庆八一活动方案
2014/01/25 职场文书
《雨点》教学反思
2014/02/12 职场文书
商场促销活动策划方案
2014/08/18 职场文书
警告通知
2015/04/25 职场文书
监护人证明
2015/06/19 职场文书
聘任协议书(挂靠)
2015/09/21 职场文书
导游词之天下银坑景区
2019/11/21 职场文书