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

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

除非在子类中也定义__slots__,这样,子类允许定义的属性就是自身的__slots__加上父类的__slots__

python slots的更多相关文章

  1. python slots源码分析

    上次总结Python3的字典实现后的某一天,突然开窍Python的__slots__的实现应该也是类似,于是翻了翻CPython的源码,果然如此! 关于在自定义类里面添加__slots__的效果,网上 ...

  2. python object对象

    动态语言的对象属性 既然都是动态语言,自然python和熟知的JavaScript很像,建一个空对象用来存放所有的数据,看看js: var data = {}; data.name = 'CooMar ...

  3. 【万字长文】别再报班了,一篇文章带你入门Python

    本文始发于个人公众号:TechFlow,原创不易,求个关注 最近有许多小伙伴后台联系我,说目前想要学习Python,但是没有一份很好的资料入门.一方面的确现在市面上Python的资料过多,导致新手会不 ...

  4. 万字长文,一篇文章带你入门Python

    注释 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大家提供 ...

  5. slots - Python的结构体 转

          上个月看了篇文章 “SAVING 9 GB OF RAM WITH PYTHON’S __SLOTS__”,原来Python也有类似结构体的东东.拖了一个月才写这篇,是因为太久没看pyth ...

  6. 细说python类2——类动态添加方法和slots(转)

    先说一下类添加属性方法和实例添加属性和方法的区别, 类添加属性属于加了一个以类为全局的属性(据说叫静态属性),那么以后类的每一个实例化,都具有这个属性.给类加一个方法也如此,以后类的每一个实例化都具备 ...

  7. Python内存优化:Profile,slots,compact dict

    实际项目中,pythoner更加关注的是Python的性能问题,之前也写过一篇文章<Python性能优化>介绍Python性能优化的一些方法.而本文,关注的是Python的内存优化,一般说 ...

  8. Python之面向对象slots与迭代器协议

    Python之面向对象slots与迭代器协议 slots: # class People: # x=1 # def __init__(self,name): # self.name=name # de ...

  9. Python动态绑定属性slots的使用

    当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.废话不多说,我们看一个例子: class Person(object): pass ...

随机推荐

  1. virtualbox+vagrant学习-1-环境安装及vagrantfile的简单配置-Mac系统

    在学习docker-machine时,发现需要使用到虚拟化平台,所以选择了使用virtualBox. 然后后面发现需要使用vagrant来在mac系统中作为虚拟机管理软件,所以下面将会简述我自己学习使 ...

  2. mybatis逆向工程之maven工程

    maven工程与动态web工程存在差异,不过大体是相同的 注意:运行成功后记得refresh刷新下,否则看不到 一.在pom文件中进行如下配置 <project xmlns="http ...

  3. Android学习之多触点滑动

    知识点: 1.对矩阵:Matrix类熟悉,链接:https://blog.csdn.net/jdsjlzx/article/details/52741445 2.MotionEvent详解:https ...

  4. 《Google软件测试之道》测试工程师

    愿和我一样读过这本书的人有所共鸣或者启发,愿没读过这本书的人,能获得一点点收获... 说到软件测试工程师,首先我们需要明白一个问题,软件测试工程师的职责是什么? 关于这个话题,不同的人有不同的定义:抛 ...

  5. timeout可以实现当一个命令在规定时间内不返回就强制返回的功能 + 杀毒安装ClamAV nmap 速度 比Telnet 快

    [root@xiaowei ~]# cat telnetport.sh #!/bin/bash Port=25223 timeout 2 ssh root@127.0.0.1 "telnet ...

  6. LeetCode112:Path Sum

    正常写法 bool HasPathSum(TreeNode root, int sum) { bool ret=false; if(root==null)return false; if(root.l ...

  7. highcharts中把X轴的名字竖着显示

    Highcharts.chart('container', { chart: { type: 'column' }, title: { text: 'Auto rotation limit' }, s ...

  8. 自行实现高性能MVC

    wcf虽然功能多.扩展性强但是也面临配置忒多,而且restful的功能相当怪异,并且目前没法移植.asp.net core虽然支持webapi,但是功能也相对繁多.配置复杂.就没有一个能让码农们安安心 ...

  9. 【JVM.2】垃圾收集器与内存分配策略

    垃圾收集器需要完成的3件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 在前一节中介绍了java内存运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程而生,随线程而灭:栈 ...

  10. spring-session-data-redis包冲突

    包冲突 spring 的包很容易冲突, 因为写软件的人在兼容性上处理的不够,一般不检测重复加载. spring-session-data-redis 引用后, 一定要把 spring-session ...