动态非常灵活, 创建一个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. Swift开发教程--怎样播放图片动画

    废话少说,直接上代码: var barsAnim = UIImageView(frame: self.view.frame); barsAnim.animationImages = NSArray() ...

  2. ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column XXX at row 1

    本错误为:该列的插入格式有误 修改该表中该列的字符集为utf-8 网上办法: )不能插入中文解决办法: 向表中插入中文然后有错误. mysql> insert into users values ...

  3. 启用了不安全的HTTP方法解决办法 IBM APPSCAN

    启用了不安全的HTTP方法解决办法  IBM APPSCAN     安全风险:       可能会在Web 服务器上上载.修改或删除Web 页面.脚本和文件. 可能原因:       Web 服务器 ...

  4. Apache Flink 1.5.1 Released

    Apache Flink: Apache Flink 1.5.1 Released http://flink.apache.org/news/2018/07/12/release-1.5.1.html ...

  5. 通俗易懂EJB

    摘自:http://blog.csdn.net/jojo52013145/article/details/5783677 1. 我们不禁要问,什么是"服务集群"?什么是" ...

  6. javascript数据基本类型和引用类型

    JavaScript基本数据类型: js基本数据类型包括:undefined,null,number,boolean,string.基本数据类型是按值访问的,就是说我们可以操作保存在变量中的实际的值. ...

  7. LWIP在STM32上的移植

    本文做记录摘抄,加上自己的体会: 文章标题:STM32使用LWIP实现DHCP客户端 http://www.cnblogs.com/dengxiaojun/p/4379545.html 该文章介绍了几 ...

  8. button在firefox 和 ie 下的问题

    最近做了一个关于数据库管理的项目,因为不用考虑ie9以下的兼容性,所以一股脑的写完啦,到测试的时候发现了一个bug IE和火狐下有个模块关闭按钮的hover没有反应,ie不行就算了,火狐怎么也不行?我 ...

  9. I.MX6 boot from Micro SD

    /***************************************************************************** * I.MX6 boot from Mic ...

  10. NSError分析

    在iOS开发中,NSError的使用非常常见,使用也比较简单,也正因为简单,所以对这一部分知识不甚注重.但是近期在做app底层网络封装时发现了一些问题.我使用的网络框架是AFNetworking,AF ...