python学习日记(OOP——@property)
在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改:
s = Student()
s.score = 9999
这显然不合逻辑。为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数:
class Student(object):
def __init__(self,score):
self.__score = score
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
现在,对任意的Student实例进行操作,就不能随心所欲地设置score了:
s = Student(50)
print(s.get_score())
s.set_score(999)

但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。
有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?对于追求完美的Python程序员来说,这是必须要做到的!
还记得装饰器(decorator)可以给函数动态加上功能吗?对于类的方法,装饰器一样起作用。Python内置的@property装饰器就是负责把一个方法变成属性调用的:
class Student(object):
def __init__(self,score):
self.__score = score
@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
@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:
s = Student(50)
print(s.score)#相当于s.get_score()
s.score = 999#相当于s.set_score(999)
注意到这个神奇的@property,我们在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。
还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:
class Student(object):
def __init__(self,birth):
self.__birth = birth
@property
def birth(self):
return self.__birth
@birth.setter
def birht(self,value):
self.__birth = value
@property
def age(self):
return 2018 - self.__birth b = Student(1999)
print(b.birth)
b.birht = 2009
print(b.birht)
print(b.age)
上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。
小结
@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性
练习
请利用@property给一个Screen对象加上width和height属性,以及一个只读属性resolution:
class Screen(object):
pass
...
# 测试:
s = Screen()
s.width = 70
s.height = 80
print('resolution =', s.resolution)
if s.resolution == 5600:
print('测试通过!')
else:
print('测试失败!')
参考源码:
python学习日记(OOP——@property)的更多相关文章
- python学习日记(OOP——类的内置方法)
__str__和__repr__ 改变对象的字符串显示__str__,__repr__ 我们先定义一个Student类,打印一个实例: class Student(object): def __ini ...
- Python 学习日记(第三周)
知识回顾 在上一周的学习里,我学习了一些学习Python的基础知识下面先简短的回顾一些: 1Python的版本和和安装 Python的版本主要有2.x和3.x两个版本这两个版本在语法等方面有一定的区别 ...
- Python学习日记 --day2
Python学习日记 --day2 1.格式化输出:% s d (%为占位符 s为字符串类型 d为数字类型) name = input('请输入姓名') age = int(input('请输入年龄 ...
- python学习日记(基础数据类型及其方法01)
数字 int 主要是用于计算的,常用的方法有一种 #既十进制数值用二进制表示时,最少使用的位数i = 3#3的ASCII为:0000 0011,即两位 s = i.bit_length() print ...
- Python学习日记(一):拜见小主——Python
近日学习Python,特将学习过程及一点心得记录于此. 由于之前做过一个Java爬虫的项目,虽然很长时间没有碰过爬虫,但是小郭同学有一颗不死的爬虫心,哈哈.最近在互联网上找一些电影的时候,有很多电影只 ...
- Python学习 Day 9 property 多重继承 Mixin
在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 为了限制score的范围,可以通过一 ...
- python学习日记(OOP——静态方法和类方法)
classmethod 类方法在Python中使用比较少,类方法传入的第一个参数为cls,是类本身.并且,类方法可以通过类直接调用,或通过实例直接调用.但无论哪种调用方式,最左侧传入的参数一定是类本身 ...
- python学习日记(OOP数据封装)
class Student(object): def __init__(self,name,score): self.name = name self.score = score li = Stude ...
- python学习日记(OOP访问限制)
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的na ...
随机推荐
- Vmware workstation V2V
错误提示 检查虚拟机文件是否有快照,用WORKSTATION打开虚拟机后删除所有快照再使用converter导入 检查VMx文件中声明的vmdk路径是否与文件实际路径相 ...
- TabLayout您可能不知道的实用用法
一.修改点击的动画 函数:setUnboundedRipple 这是默认的点击的动画 我们用代码修改一下: mGlueTabLayout.setUnboundedRipple(true); 这是之后的 ...
- Django 如何让ajax的POST方法带上CSRF令牌
问题 大家知道,在大前端领域,有一种叫做ajax的东东,即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),它被用来在不刷新页面的情况下,提 ...
- CGI 、FastCGI、PHP-CGI、PHP-FPM 定义以及与nginx的应用关系
CGI common gateway interface,简称cgi,简而言之就是一个接口,一种协议.它的作用就是帮助服务器与语言通信. 这里以nginx和php为例,因为nginx和php的语言不通 ...
- centos7中mail实测(qq邮箱)
一.安装mailx sendmail 1.1查看是否已经安装 yum install -y mailx sendmail 如果已经安装,会提示已经安装,没有安装会自动安装. ...
- chrome打开收藏夹的网站在新的标签页
chrome浏览器在新的标签页打开收藏夹的网址,现在设置不了,而且右键,在新标签页中打开有点烦..下面说说直接打开的方式. 方法1: 鼠标滚轮,直接点击收藏夹的网址,即可 方法2: ctrl + 鼠标 ...
- 持续代码质量管理-SonarQube-7.3简单使用
安装了SonarQube以及Sonar Scanner之后,就需要那代码检测了.当然为了方便我们使用已有现成的demo,知道到对应的git地址下载即可. 1. sonar-examples下载 htt ...
- LeetCode算法题-Longest Continuous Increasing Subsequence(Java实现)
这是悦乐书的第286次更新,第303篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第154题(顺位题号是674).给定未排序的整数数组,找到最长连续增加子序列的长度.例如 ...
- 【Teradata SQL】FALLBACK表改为NO FALLBACK表
FALLBACK表在数据库中会留存双份数据,增加了数据可用性,但浪费了存储空间.变更表属性语句如下: alter table tab_fallback ,no fallback;
- Redis学习笔记(1)——Redis简介
一.Redis是什么? Remote Dictionary Server(Redis) 是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value ...