__slots__ 和 @property
动态非常灵活, 创建一个class后, 给实例绑定一个属性:
>>> class Bird:
... pass
...
>>> s = Bird()
>>> s.name = 'bob'
>>> s.name
bob
也可以给实例绑定一个方法, 但是这对另一个实例是无效的:
>>> def age(self,age):
... self.age = age
...
>>> from types import MethodType
>>>
>>> s.age = MethodType(age,s,Bird)
>>> s.age(0.5)
>>> print s.age
0.5 >>> s2 = Bird()
>>> s2.age(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Bird instance has no attribute 'age'
为了给所有实例都绑定方法,可以给class绑定方法, 绑定后所以属于该类的实例均可调用:
>>> def is_running(self):
... print 'running...'
...
>>> Bird.is_running = MethodType(is_running, None, Bird)
>>> s3 = Bird()
>>> s3.is_running()
running...
>>> s2.is_running()
running...
__slots__
如果我们需要限制class的属性怎么办? 比如说我们定义一个Person类, 只允许对Person实例添加 name age属性, 不允许添加gender属性! 所以我们需要使用 __slots__
>>> class Person(object):
... __slots__ = ('name','age')
...
>>> s = Person()
>>> s.name = 'Johb'
>>> s.age = ''
>>> s.gender = 'male'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Person' object has no attribute 'gender'
但是对于Person的子类是不起作用的, 除非子类也定义 __slots__
>>> class SuperPerson(Person):
... pass
...
>>> s = SuperPerson()
>>> s.aaaaa = 'no restriction'
>>> s.aaaaa
'no restriction'
注意: 因为Python的历史遗留问题, 在2.x版本中, 如果类后面没有跟object , __slots__的限制将会无效
>>> class Person:
... __slots__=('name','age')
...
>>> s.gender = 'male'
>>> s.gender
'male'
@property
如果不对age做限制,我们可以任意设置age的值, 显然这是不规范的.
>>> s.age = 99999999
>>> s.age = 'aaaaaa'
当然我们可以麻烦一点, 设置两个函数:
class Person(object):
def get_age(self):
return self.age
def set_age(self,value):
if not isinstance(value, int):
raise ValueError('Age must be an integer')
if value < 0 or value > 100:
raise ValueError('Age must between 0 ~ 100')
self.age = value
>>> s = Person()
>>> s.set_age(22)
>>> se.get_age()
>>> 22
>>> s.set_age(11111)
Traceback (most recent call last):
.................................
ValueError: Age must between 0 ~ 100
使用更简单的方法@property, 把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@age.setter,负责把一个setter方法变成属性赋值.
class Person(object):
@property
def age(self):
return self.age @age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError('age must be an integer!')
if value < 0 or value > 100:
raise ValueError('age must between 0~100')
self.age = value >>>s = Person()
>>>s.age = 40
>>>s.age
40
>>>s.age = 11111
Traceback (most recent call last):
.................................
ValueError: Age must between 0 ~ 100
__slots__ 和 @property的更多相关文章
- Python -- OOP高级 -- __slots__、@property
__slots__属性可以设置 允许被设置的属性 class Student: __slots__ = ("name", "age") >>> ...
- 【Python】__slots__ 、@property、多重继承、定制类、枚举类、元类
__slots__ @property 多重继承 定制类 枚举类 元类 [使用__slots__] 1.动态语言的一个特点就是允许给实例绑定任意的方法和变量,而静态语言(例如Java)必须事先将属性方 ...
- Python——详解__slots__,property和私有方法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第11篇文章,我们来聊聊面向对象的一些进阶使用. __slots__ 如果你看过github当中一些大牛的代码,你会 ...
- python学习第十七天 --定制类
何为定制类? Python的class允许定义许多特殊方法,可以让我们非常方便地生成特定的类.在类中应用或者重写python的特殊方法,得到的类,就是定制类. 大家都知道print的用法.见下面例子 ...
- Python学习--11 面向对象高级编程
多重继承 Python里允许多重继承,即一个类可以同时继承多个类: class Mammal(Animal): pass class Runnable(object): def run(self): ...
- 【Python系统学习】基础篇
这次真的是最后一次了!第三次滚Python的基础.走了太多弯路.认真一点!菜鸟! 教程 转义字符 \ 可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\ ...
- 【JulyEdu-Python基础】第 6 课:高级面向对象
使用@property添加属性和自定义属性 __slots__和property 方法和属性的动态绑定 使用__slots__限定class实例能添加的属性 __slots__仅对当前类实例起作用,对 ...
- python学习笔记(12):高级面向对象
一.__slots__和property 1.__slots__魔术函数动态的添加方法和属性 2.直接暴露属性的局限性 3.使用get/set方法 4.利用@property简化get/set方法 5 ...
- Python重学记录2
这几天学的不多,只是看了一下相关的视频.最近看的部分比较难,装饰器没有搞懂,__slots__和property也不太明白(这两个知识点是在公交车上看的视频,因为1.5倍速度放的视频,看得快,不太明白 ...
随机推荐
- 给大二学生——能够再坚持一年的ACM
[来信] 我是大二学生,就读于一所非常普通的大学.学校ACM基本零起步,去年才開始搞,我大一大二花了非常多时间搞acm,如今不太想放弃.但学校基本没人愿意搞这个. 非常快就要大三了,我一直在纠结要不要 ...
- linux 输入子系统(4) intput_dev 接口描述
Name struct input_dev - represents an input device Synopsis struct input_dev { const char * name; // ...
- 浅谈JavaScript的事件(事件流)
事件流描述的是从页面中接收事件的顺序.IE的事件流失事件冒泡,而Netspace的事件流失事件捕获. 事件冒泡 IE的事件流叫事件冒泡,即事件开始时,由具体的元素(文档中嵌套层次最深的节点)接收,然 ...
- 对FreeMarker技术的思考
依照静态非静态来划分网页分为两种:静态网页和非静态网页,究其优缺点而言,静态网页在用户訪问的时候响应快,可是因为里面的数据是写死的.所以致命的缺陷就是数据不能动态显示.非静态页面(如jsp)数据能够动 ...
- Spark 学习笔记:(三)Spark SQL
参考:https://spark.apache.org/docs/latest/sql-programming-guide.html#overview http://www.csdn.net/arti ...
- 使用URL dispatcher的范例
在上面的一篇文章中,我们介绍了怎样使用URL disptacher.在这篇文章中,我们来通过一个范例更进一步来了解怎样实现它. 1)创建一个具有URL dispatcher的应用 我们首先打开我们的S ...
- 【翻译自mos文章】即使resource_limit = false, password的 资源限制也会生效
即使resource_limit = false, password的 资源限制也会生效 參考原文: Resource limits for passwords work even with reso ...
- 计算(!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]
(!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]] 一.JS运算符的优先级 首先要运用到的第一个 ...
- ubuntu16.04和服务器 caffe 安装
在centos6.X上安装caffe 0.编译安装gcc4.8.5 由于centos6.x中的gcc版本老旧,不支持c++11所以要安装gcc4.8.5,以下是安装教程.参考CentOS 6.4 编译 ...
- Bootloader与Kernel间参数传递机制 taglist【转】
本文转载自:http://blog.csdn.net/tommy_wxie/article/details/9187821 Tag list被用来在bootloader和Linux kernel 之间 ...