正常情况下,当我们定义了一个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__

二十二 使用__slots__的更多相关文章

  1. [分享] IT天空的二十二条军规

    Una 发表于 2014-9-19 20:25:06 https://www.itsk.com/thread-335975-1-1.html IT天空的二十二条军规 第一条.你不是什么都会,也不是什么 ...

  2. Bootstrap <基础二十二>超大屏幕(Jumbotron)

    Bootstrap 支持的另一个特性,超大屏幕(Jumbotron).顾名思义该组件可以增加标题的大小,并为登陆页面内容添加更多的外边距(margin).使用超大屏幕(Jumbotron)的步骤如下: ...

  3. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】

    <Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...

  4. 二十二、OGNL的一些其他操作

    二十二.OGNL的一些其他操作 投影 ?判断满足条件 动作类代码: ^ $   public class Demo2Action extends ActionSupport {     public ...

  5. WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]

    原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...

  6. VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池

    VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...

  7. Bootstrap入门(二十二)组件16:列表组

    Bootstrap入门(二十二)组件16:列表组 列表组是灵活又强大的组件,不仅能用于显示一组简单的元素,还能用于复杂的定制的内容. 1.默认样式列表组 2.加入徽章 3.链接 4.禁用的列表组 5. ...

  8. JAVA之旅(二十二)——Map概述,子类对象特点,共性方法,keySet,entrySet,Map小练习

    JAVA之旅(二十二)--Map概述,子类对象特点,共性方法,keySet,entrySet,Map小练习 继续坚持下去吧,各位骚年们! 事实上,我们的数据结构,只剩下这个Map的知识点了,平时开发中 ...

  9. 备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)

    备忘录模式 Memento   沿着脚印,走过你来时的路,回到原点.     苦海翻起爱恨   在世间难逃避命运   相亲竟不可接近   或我应该相信是缘份   一首<一生所爱>触动了多少 ...

  10. 二十二. Python基础(22)--继承

    二十二. Python基础(22)--继承 ● 知识框架   ● 继承关系中self的指向 当一个对象调用一个方法时,这个方法的self形参会指向这个对象 class A:     def get(s ...

随机推荐

  1. 浅谈cocosd之autorelease\retain\release的理解

    三种情况,引出问题:   1) new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这个对象时,则会出现野指针情况. ==> 于是出现了引用计数的释放管理机制. 2) 对于一 ...

  2. libiop网络库数据结构和基础知识

    最近朋友推荐,学习了libiop这个网络库,作者封装的很全面,代码很简洁 适合初学者学习基于事件驱动的网络io 先看看iop_def.h, 这里面定义了常用的数据结构 tag_iop_base_t 主 ...

  3. need

    php面试题: http://lib.csdn.net/article/php/43624 小程序: 官方手册: https://mp.weixin.qq.com/debug/wxadoc/dev/d ...

  4. duilib 给List表头增加百分比控制宽度的功能

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/42503147 最近项目里需要用到包含表头列表,而窗体大小改变后,每个列表 ...

  5. 安装配置hexo icarus主题配置

    安装部分配置hexo icarus主题配置 安装icarus 直接下载主题模块放到blog项目 ,blog项目根目录执行 git clone https://github.com/ppoffice/h ...

  6. 启动EMQ(emqtt)时报错找不到libsctp.so.1

    libsctp.so.1: cannot open shared object file: No such file or directory   发现没有安装sctp   [root@localho ...

  7. 改变你一生的编辑器:VSCode使用总结

    开发十年,只剩下这套Java开发体系了 >>>   前言:vscode是微软出品的,基于Electron和TypeScript的,现在已经是最火的一款文本编辑器.我认为vscode是 ...

  8. linux的MySQL设为开机启动

    linux开启启动的程序一般放在/etc/rc.d/init.d/里面,/etc/init.d/是其软连接 mysql设为linux服务cp /usr/local/mysql5/share/mysql ...

  9. JAVA多线程提高五:原子性操作类的应用

    当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可能i不等于3,而是等于2.因为A和B线程在更新变量i ...

  10. HDU 1045 Fire Net (深搜)

    题目链接 Problem DescriptionSuppose that we have a square city with straight streets. A map of a city is ...