在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字符串特性及常用字符串方法的简单笔记
Jan 04 Python
Python实现Logger打印功能的方法详解
Sep 01 Python
Python实现动态图解析、合成与倒放
Jan 18 Python
Windows下的Jupyter Notebook 安装与自定义启动(图文详解)
Feb 21 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
Apr 23 Python
纯用NumPy实现神经网络的示例代码
Oct 24 Python
解决python xlrd无法读取excel文件的问题
Dec 25 Python
利用Pyhton中的requests包进行网页访问测试的方法
Dec 26 Python
python实现自动获取IP并发送到邮箱
Dec 26 Python
keras获得model中某一层的某一个Tensor的输出维度教程
Jan 24 Python
基于Tensorflow一维卷积用法详解
May 22 Python
用python写一个带有gui界面的密码生成器
Nov 06 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模板IF标签用法详解
2014/07/01 PHP
PHP添加图片水印、压缩、剪切的封装类
2015/08/17 PHP
Thinkphp5 自定义上传文件名的实现方法
2019/07/23 PHP
php 的多进程操作实践案例分析
2020/02/28 PHP
Laravel5.3+框架定义API路径取消CSRF保护方法详解
2020/04/06 PHP
js 提交和设置表单的值
2008/12/19 Javascript
jQuery 动画基础教程
2008/12/25 Javascript
JavaScript 动态添加表格行 使用模板、标记
2009/10/24 Javascript
jquery 插件实现图片延迟加载效果代码
2010/02/06 Javascript
JavaScript中的property和attribute介绍
2011/12/26 Javascript
浅谈Javascript的静态属性和原型属性
2015/05/07 Javascript
JS实现禁止高频率连续点击的方法【基于ES6语法】
2017/04/25 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(下)
2018/04/18 Javascript
React diff算法的实现示例
2018/04/20 Javascript
Vue组件内部实现一个双向数据绑定的实例代码
2019/04/04 Javascript
详解async/await 异步应用的常用场景
2019/05/13 Javascript
微信小程序实现树莓派(raspberry pi)小车控制
2020/02/12 Javascript
从零开始在vue-cli4配置自适应vw布局的实现
2020/06/08 Javascript
跟老齐学Python之玩转字符串(2)
2014/09/14 Python
python自定义类并使用的方法
2015/05/07 Python
python利用datetime模块计算时间差
2015/08/04 Python
Python中按键来获取指定的值
2019/03/02 Python
python定时任务 sched模块用法实例
2019/11/04 Python
关于python3.9安装wordcloud出错的问题及解决办法
2020/11/02 Python
小学国庆节活动方案
2014/02/11 职场文书
推荐信格式范文
2014/05/09 职场文书
教师专业自荐信
2014/05/31 职场文书
法人代表任命书范本
2014/06/05 职场文书
超市理货员岗位职责
2014/07/04 职场文书
运动会广播稿诗歌版
2014/09/12 职场文书
个人融资协议书
2014/10/02 职场文书
学校党的群众路线教育实践活动整改措施
2014/10/25 职场文书
先进教师事迹材料
2014/12/16 职场文书
医院保洁员管理制度
2015/08/05 职场文书
结婚喜宴祝酒词
2015/08/10 职场文书
win10截图快捷键win+shift+s没有反应无法截图怎么解决?
2022/08/14 数码科技