动态非常灵活, 创建一个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. 解决:Android4.3锁屏界面Emergency calls only - China Unicom与EMERGENCY CALL语义反复

    从图片中我们能够看到,这里在语义上有一定的反复,当然这是谷歌的原始设计.这个问题在博客上进行共享从表面上来看着实没有什么太大的意义,只是因为Android4.3在锁屏功能上比起老版本号做了非常大的修改 ...

  2. mysql关闭skip-grant-tables快速重置mysql密码

    如果你忘记了mysql密码几乎是没有什么好办法可以直接修改密码了,但我们可以在my.ini把加上skip-grant-tables,然后重启mysql就不需要密码了,这时我们再修改root密码,最后再 ...

  3. python day - 19 抽象类 接口类 多态 封装

    一. 抽象类接口类即制定一个规范 特点: 1.不可被实例化. 2.规范子类当中必须事先某个方法. 3.在python中有原生实现抽象类的方法,但没有原生实现接口类的方法. 例题:制定一个规范就是,子类 ...

  4. 定时任务Timer

    一.Timer介绍 java.util.Timer java.util.TimerTask Timer是一个定时器类,通过该类可以为指定的定时任务进行配置.TimerTask类是一个定时任务类,该类实 ...

  5. Duplicate Observed Data

    在翻看<重构-改善既有代码的设计>这本经典的书,书中就介绍了一个重构方法--Duplicate Observed Data 复制被监视数据的重构方法,使用这种方法能够使界面和对数据的操作隔 ...

  6. table 中的thead tbody

    通过thead 下的tr 设置样式以及 tbody 下的 tr 设置样式 避免冲突 <table> <thead> <tr> <td> </td& ...

  7. mysql表分区 partition

    表分区 partition 当一张表的数据非常多的时候,比如单个.myd文件都达到10G, 这时,必然读取起来效率降低. 可不可以把表的数据分开在几张表上? 1: 从业务角度可以解决.. (分表,水平 ...

  8. redis02---对于key的操作命令

    Redis对于key的操作命令 del key1 key2 ... Keyn 作用: 删除1个或多个键 返回值: 不存在的key忽略掉,返回真正删除的key的数量 rename key newkey ...

  9. react native 中的redux 理解

    redux 中主要分为三大块,分别是Action Reducer 与Store. 1.Action是js的一个普通对象,是store数据的唯一来源.通过store.dispath()讲action传到 ...

  10. hihocoder #1039 : 字符消除 ( 字符串处理类 ) 好久之前做的题目,具体的算法代码中阅读吧

    #1039 : 字符消除 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最近在玩一个字符消除游戏.给定一个只包含大写字母"ABC"的字符串s,消 ...