Python面向对象高级编程-@property
使用@property
在绑定属性时,如果直接把属性暴露出去,虽然写起来简单,但是没法检查参数,导致可以把成绩随便改:
>>> class Student(object):
pass >>> s =Student()
>>> s.score=999
>>> s.score
999
这显然不符合逻辑,为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数:
>>> class Student(object):
def get_score(self):
return self.score
def set_score(self,value):
if not isinstance(value,int):
raise ValueError("score must be an integer")
if value <0 or value > 100:
raise ValueError("score must between 0~100")
self.score = value >>> s = Student()
>>> s.set_score('a') Traceback (most recent call last):
File "<pyshell#57>", line 1, in <module>
s.set_score('a')
File "<pyshell#54>", line 6, in set_score
raise ValueError("score must be an integer")
ValueError: score must be an integer
>>> s.set_score(99999) Traceback (most recent call last):
File "<pyshell#58>", line 1, in <module>
s.set_score(99999)
File "<pyshell#54>", line 8, in set_score
raise ValueError("score must between 0~100")
ValueError: score must between 0~100
>>> s.set_score(99)
>>> s.get_score()
99
>>>
现在,对任意的Student实例进行操作,就不能随心所欲地设置score了:
但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。
有没有技能检查参数,有可以用雷士属性这样简单地方式来访问类的变量?
记得装饰器(decorator)可以给函数动态加上功能?对于累的方法,装饰器一样起作用,Python内置的@property装饰器就是负责把一个方法变成属性调用的:
>>> class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
>>> s = Student()
>>> s.score =99
>>> s.score = 999
Traceback (most recent call last):
File "<pyshell#76>", line 1, in <module>
s.score = 999
File "<pyshell#73>", line 12, in score
raise ValueError('score must between 0 ~ 100!')
ValueError: score must between 0 ~ 100!
>>> s.score = 'a'
Traceback (most recent call last):
File "<pyshell#77>", line 1, in <module>
s.score = 'a'
File "<pyshell#73>", line 10, in score
raise ValueError('score must be an integer!')
ValueError: score must be an integer!
>>>
注意这个@property,在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。
还可以定义只读属性,值定义getter方法,不定义setter方法就是一个只读属性:
>> class Student(object):
@property
def birth(self):
return self._birth
@birth.setter
def birth(self,value):
self._birth = value
@property
def age(self):
return 2017 - self._birth >>> s = Student()
>>> s.birth = 1995 >>> s.age
22
>>> s.age = 23 Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
s.age = 23
AttributeError: can't set attribute
>>>
上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。
总结
@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样程序运行时就减少了出错的可能性。
Python面向对象高级编程-@property的更多相关文章
- python面向对象高级编程
正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: >>> class Studen ...
- Python面向对象高级编程:@property--把方法变为属性
为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数: >>> ...
- python 面向对象高级编程
数据封装.继承和多态只是面向对象程序设计中最基础的3个概念.在Python中,面向对象还有很多高级特性,允许我们写出非常强大的功能. 我们会讨论多重继承.定制类.元类等概念.
- python面向对象高级:@property
@property 把方法『变成』了属性,广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性. 最大的作用就是既能检查参数,又可以用类 ...
- Python面向对象高级编程-__slots__、定制类,枚举
当在类体内定义好各种属性后,外部是可以随便添加属性的,Python中类如何限制实例的属性? Python自带了很多定制类,诸如__slots__,__str__ __slots__ __slots__ ...
- Python面向对象高级编程:__slot__(给实例添加方法、属性)
纲要: 本章总的来说是给实例添加属性,给类添加方法两个主题,以及相应的作用范围.总结如下: 1.给实例添加属性(作用范围:当然是只对当前实例有效): 2.用__slots__限制可以给实例添加的属性( ...
- Python面向对象高级编程-_slots_
使用_slots_ 正常情况下,当定义一个class,创建一个class的实例后,可以给实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: >>> class Stu ...
- C++面向对象高级编程(九)Reference与重载operator new和operator delete
摘要: 技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一 Reference 引用:之前提及过,他的主要作用就是取别名,与指针很相似,实现也是基于指针. 1.引用必须有初值,且不能引用nul ...
- C++面向对象高级编程(八)模板
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 这节课主要讲模板的使用,之前我们谈到过函数模板与类模板 (C++面向对象高级编程(四)基础篇)这里不再说明 1.成员模板 成员模板:参数为tem ...
随机推荐
- iOS 转盘抽奖游戏(原生)
转盘抽奖游戏在一般的app中都会有,应该算是一种吸引用户的一种手段.在项目中集成转盘抽奖游戏,大都采用h5的方式来实现,但是由于项目需求,需要在app中使用原生来实现转盘抽奖.实现原理也很简单,中间的 ...
- 碉堡完整的高性能PHP应用服务器appserver
完全企业级的开发模式,是一个多线程的 PHP 应用服务器,实现真正多线程的 PHP 编程,高效安全而且快速,以Magento 为例比基于 Nginx的标准安装要快 50%.概念上非常像 Java 的 ...
- windows7常用操作命令
1.打开命令行 按住Windows键加R键,打开运行窗口 2.打开笔记本 运行窗口中输入:notepad,点击确定或回车,打开记事本工具 主要作用:浏览网页时,看到一些有用的话,那么你是怎么把它记录下 ...
- java.lang.NoSuchMethodError: org.apache.spark.util.ThreadUtils$.newDae
-classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1. ...
- 使用randA()生成randB()
randA()表示可以随机生成1--A的整数 rand7()生成rand5() int Rand5(){ int x = ~(1<<31); // max int while(x > ...
- cronatb
CRONTAB语法及应用 1:查看当前用户的定时任务 [oracle@localhost ~]$ crontab -l * * * * * /home/oracle/test.sh >/dev/ ...
- IO模型(阻塞、非阻塞、多路复用与异步)
IO模型 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同环境下给出的答案也是不一的.所以先限定一下上下文是非常有必要的. 本文讨论的背景是Linux环境下的network I ...
- Iptables规则执行顺序详解
1.The first is the mangle table which is responsible for the alteration of quality of service bits ...
- Angular4中的依赖注入
在Angular中使用依赖注入,可以帮助我们实现松耦合,可以说只有在组件中使用依赖注入才能真正 的实现可重用的组件. 如果我们有个服务product.service.ts,其中export了一个Pro ...
- ES6快速入门使用
https://www.jianshu.com/p/061304806bda Babel-webpack的配置 Bebal官方文档 前段项目我想使用ES6的语法我应该怎么做呢?我们可以查看Babel的 ...