正常情况下,当我们定义了一个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实例添加nameage属性。

为了达到限制的目的,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__

最新文章

  1. javascript小技巧
  2. ASP.NET页面事件:顺序与回传详解
  3. 浅谈SEO-收录(二)
  4. 创建maven项目时,提示 overlaps the workspace location
  5. BZOJ3339 Rmq Problem
  6. Hortworks Hadoop生态圈简介
  7. delphi-json组件,速度非常快,要比superobject快好几倍
  8. JS获取终端屏幕、浏览窗口的相关信息
  9. 8QQ消息框
  10. mysql日志详细解析【转载】
  11. Struts2基础学习(八)&mdash;Struts2防止表单重复提交
  12. Python 调用让系统自动调用默认程序打开文件?
  13. 【2017-05-18】WebForm的Repeater控件及简单控件
  14. bzoj4278
  15. 三星GT-N8010刷机教程
  16. mysql添加类似oracle的伪列及查看表信息
  17. getWidth() 和 getMeasuredWidth()的区别
  18. Mysql优化性能优化21条
  19. Monkeyrunner的相关总结
  20. HDUOJ---2082

热门文章

  1. Meeting HDU - 5521 虚点建图
  2. 题解【bzoj2440 [中山市选2011]完全平方数】
  3. HTML入门(一)
  4. C++ Arithmetic Exception
  5. HTML DOM 节点介绍(nodeName,nodeValue,nodeType)
  6. asp.net后台代码动态添加JS文件和css文件的引用
  7. javascript中字符串的两种定义形式
  8. 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]
  9. 使用Forms Authentication
  10. SMB MS17-010 利用(CVE-2017-0144 )