__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倍速度放的视频,看得快,不太明白 ...
随机推荐
- 设计模式学习笔记——Decorator装饰模式
装饰模式的作用或动机就是,尽量避免继承,而使用关联.原因是层层继承下来,内容会越来越多,有失控的危险.就扩展性而言,用关联比用继承好.所谓的关联,A使用了B,就叫A关联了B. Component 抽象 ...
- 使用URL dispatcher的范例
在上面的一篇文章中,我们介绍了怎样使用URL disptacher.在这篇文章中,我们来通过一个范例更进一步来了解怎样实现它. 1)创建一个具有URL dispatcher的应用 我们首先打开我们的S ...
- x$kccle视图深入剖析
今天是2014-05-27,实在无聊顺便研究一下x$kccle的内容吧.例如以下所有是自己分析和实验结果,真实可靠. 1.怎样获得v$log的底层表?我们能够通过autotrace完毕查看如 ...
- 搭建双系统后没有windows的引导程序
因为安装linux系统前没有安装引导程序,导致安装了linux系统后进入linux系统没有windows的引导程序,网上找了很多解决办法,也不能说是不好使,只是作为新手小白来说有点难以理解,最后无意中 ...
- HDU 6122 今夕何夕 【数学公式】 (2017"百度之星"程序设计大赛 - 初赛(A))
今夕何夕 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- IE67下float左右对齐
例子: <style> .h1{text-align: left;} .leftA{color: #000} .rightA{color: #ccc; float: right;} < ...
- #import @import #include
1.在xcode5以后 ,Replace #import <Cocoa/Cocoa.h> with @import Cocoa; 在这之前 必须手动设置一下才能用. 2.#import 与 ...
- 恢复MySQL数据库删除的数据
在日常运维工作中,对于数据库的备份是至关重要的!数据库对于网站的重要性使得我们对 MySQL 数据库的管理不容有失!然而是人总难免会犯错误,说不定哪天大脑短路了,误操作把数据库给删除了,怎么办? 下面 ...
- HDU1495 非常可乐 —— BFS + 模拟
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495 非常可乐 Time Limit: 2000/1000 MS (Java/Others) M ...
- 织梦DEDE多选项筛选_联动筛选功能的实现_二次开发
织梦默认的列表页没有筛选功能,但有时候我们做产品列表页的时候,产品的字段比较多,很多人都需要用到筛选功能,这样可以让用户更方便的找到自己所需要的东西,实现这个联动筛选功能需要对织梦进行二次开发,下面就 ...