动态非常灵活, 创建一个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的更多相关文章

  1. Python -- OOP高级 -- __slots__、@property

    __slots__属性可以设置 允许被设置的属性 class Student: __slots__ = ("name", "age") >>> ...

  2. 【Python】__slots__ 、@property、多重继承、定制类、枚举类、元类

    __slots__ @property 多重继承 定制类 枚举类 元类 [使用__slots__] 1.动态语言的一个特点就是允许给实例绑定任意的方法和变量,而静态语言(例如Java)必须事先将属性方 ...

  3. Python——详解__slots__,property和私有方法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第11篇文章,我们来聊聊面向对象的一些进阶使用. __slots__ 如果你看过github当中一些大牛的代码,你会 ...

  4. python学习第十七天 --定制类

    何为定制类? Python的class允许定义许多特殊方法,可以让我们非常方便地生成特定的类.在类中应用或者重写python的特殊方法,得到的类,就是定制类. 大家都知道print的用法.见下面例子 ...

  5. Python学习--11 面向对象高级编程

    多重继承 Python里允许多重继承,即一个类可以同时继承多个类: class Mammal(Animal): pass class Runnable(object): def run(self): ...

  6. 【Python系统学习】基础篇

    这次真的是最后一次了!第三次滚Python的基础.走了太多弯路.认真一点!菜鸟! 教程 转义字符 \ 可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\ ...

  7. 【JulyEdu-Python基础】第 6 课:高级面向对象

    使用@property添加属性和自定义属性 __slots__和property 方法和属性的动态绑定 使用__slots__限定class实例能添加的属性 __slots__仅对当前类实例起作用,对 ...

  8. python学习笔记(12):高级面向对象

    一.__slots__和property 1.__slots__魔术函数动态的添加方法和属性 2.直接暴露属性的局限性 3.使用get/set方法 4.利用@property简化get/set方法 5 ...

  9. Python重学记录2

    这几天学的不多,只是看了一下相关的视频.最近看的部分比较难,装饰器没有搞懂,__slots__和property也不太明白(这两个知识点是在公交车上看的视频,因为1.5倍速度放的视频,看得快,不太明白 ...

随机推荐

  1. 设计模式学习笔记——Decorator装饰模式

    装饰模式的作用或动机就是,尽量避免继承,而使用关联.原因是层层继承下来,内容会越来越多,有失控的危险.就扩展性而言,用关联比用继承好.所谓的关联,A使用了B,就叫A关联了B. Component 抽象 ...

  2. 使用URL dispatcher的范例

    在上面的一篇文章中,我们介绍了怎样使用URL disptacher.在这篇文章中,我们来通过一个范例更进一步来了解怎样实现它. 1)创建一个具有URL dispatcher的应用 我们首先打开我们的S ...

  3. x$kccle视图深入剖析

       今天是2014-05-27,实在无聊顺便研究一下x$kccle的内容吧.例如以下所有是自己分析和实验结果,真实可靠.   1.怎样获得v$log的底层表?我们能够通过autotrace完毕查看如 ...

  4. 搭建双系统后没有windows的引导程序

    因为安装linux系统前没有安装引导程序,导致安装了linux系统后进入linux系统没有windows的引导程序,网上找了很多解决办法,也不能说是不好使,只是作为新手小白来说有点难以理解,最后无意中 ...

  5. HDU 6122 今夕何夕 【数学公式】 (2017"百度之星"程序设计大赛 - 初赛(A))

    今夕何夕 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. IE67下float左右对齐

    例子: <style> .h1{text-align: left;} .leftA{color: #000} .rightA{color: #ccc; float: right;} < ...

  7. #import @import #include

    1.在xcode5以后 ,Replace #import <Cocoa/Cocoa.h> with @import Cocoa; 在这之前 必须手动设置一下才能用. 2.#import 与 ...

  8. 恢复MySQL数据库删除的数据

    在日常运维工作中,对于数据库的备份是至关重要的!数据库对于网站的重要性使得我们对 MySQL 数据库的管理不容有失!然而是人总难免会犯错误,说不定哪天大脑短路了,误操作把数据库给删除了,怎么办? 下面 ...

  9. HDU1495 非常可乐 —— BFS + 模拟

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495 非常可乐 Time Limit: 2000/1000 MS (Java/Others)    M ...

  10. 织梦DEDE多选项筛选_联动筛选功能的实现_二次开发

    织梦默认的列表页没有筛选功能,但有时候我们做产品列表页的时候,产品的字段比较多,很多人都需要用到筛选功能,这样可以让用户更方便的找到自己所需要的东西,实现这个联动筛选功能需要对织梦进行二次开发,下面就 ...