二十二 使用__slots__
2024-08-20 23:19:41
正常情况下,当我们定义了一个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) # 给实例绑定一个方法
>>> s.set_age() # 调用实例方法
>>> s.age # 测试结果
但是,给一个实例绑定的方法,对另一个实例是不起作用的:
>>> s2 = Student() # 创建新的实例
>>> s2.set_age() # 尝试调用方法
Traceback (most recent call last):
File "<stdin>", line , in <module>
AttributeError: 'Student' object has no attribute 'set_age'
为了给所有实例都绑定方法,可以给class绑定方法:
>>> def set_score(self, score):
... self.score = score
...
>>> Student.set_score = set_score
给class绑定方法后,所有实例均可调用:
>>> s.set_score()
>>> s.score >>> s2.set_score()
>>> s2.score
通常情况下,上面的set_score
方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现。
使用__slots__
但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name
和age
属性。
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__
变量,来限制该class实例能添加的属性:
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
然后,我们试试:
>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name'
>>> s.age = # 绑定属性'age'
>>> s.score = # 绑定属性'score'
Traceback (most recent call last):
File "<stdin>", line , in <module>
AttributeError: 'Student' object has no attribute 'score'
由于'score'
没有被放到__slots__
中,所以不能绑定score
属性,试图绑定score
将得到AttributeError
的错误。
使用__slots__
要注意,__slots__
定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:
>>> class GraduateStudent(Student):
... pass
...
>>> g = GraduateStudent()
>>> g.score =
除非在子类中也定义__slots__
,这样,子类实例允许定义的属性就是自身的__slots__
加上父类的__slots__
。
最新文章
- javascript小技巧
- ASP.NET页面事件:顺序与回传详解
- 浅谈SEO-收录(二)
- 创建maven项目时,提示 overlaps the workspace location
- BZOJ3339 Rmq Problem
- Hortworks Hadoop生态圈简介
- delphi-json组件,速度非常快,要比superobject快好几倍
- JS获取终端屏幕、浏览窗口的相关信息
- 8QQ消息框
- mysql日志详细解析【转载】
- Struts2基础学习(八)&mdash;Struts2防止表单重复提交
- Python 调用让系统自动调用默认程序打开文件?
- 【2017-05-18】WebForm的Repeater控件及简单控件
- bzoj4278
- 三星GT-N8010刷机教程
- mysql添加类似oracle的伪列及查看表信息
- getWidth() 和 getMeasuredWidth()的区别
- Mysql优化性能优化21条
- Monkeyrunner的相关总结
- HDUOJ---2082
热门文章
- Meeting HDU - 5521 虚点建图
- 题解【bzoj2440 [中山市选2011]完全平方数】
- HTML入门(一)
- C++ Arithmetic Exception
- HTML DOM 节点介绍(nodeName,nodeValue,nodeType)
- asp.net后台代码动态添加JS文件和css文件的引用
- javascript中字符串的两种定义形式
- 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]
- 使用Forms Authentication
- SMB MS17-010 利用(CVE-2017-0144 )