介绍Python的@property装饰器的用法


Posted in Python onApril 28, 2015

在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改:

s = Student()
s.score = 9999

这显然不合逻辑。为了限制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

现在,对任意的Student实例进行操作,就不能随心所欲地设置score了:

>>> s = Student()
>>> s.set_score(60) # ok!
>>> s.get_score()
60
>>> s.set_score(9999)
Traceback (most recent call last):
 ...
ValueError: score must between 0 ~ 100!

但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。

有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?对于追求完美的Python程序员来说,这是必须要做到的!

还记得装饰器(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

@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:

>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
 ...
ValueError: score must between 0 ~ 100!

注意到这个神奇的@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 2014 - self._birth

上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。
小结

@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。

Python 相关文章推荐
在Python中用get()方法获取字典键值的教程
May 21 Python
Python模块搜索概念介绍及模块安装方法介绍
Jun 03 Python
Python 常用的安装Module方式汇总
May 06 Python
基于Python的关键字监控及告警
Jul 06 Python
在PyCharm环境中使用Jupyter Notebook的两种方法总结
May 24 Python
Python当中的array数组对象实例详解
Jun 12 Python
python实现数据分析与建模
Jul 11 Python
Python跑循环时内存泄露的解决方法
Jan 13 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
Feb 24 Python
python 瀑布线指标编写实例
Jun 03 Python
浅析关于Keras的安装(pycharm)和初步理解
Oct 23 Python
python线程优先级队列知识点总结
Feb 28 Python
Pyhthon中使用compileall模块编译源文件为pyc文件
Apr 28 #Python
在Python中使用__slots__方法的详细教程
Apr 28 #Python
Python实现扫描局域网活动ip(扫描在线电脑)
Apr 28 #Python
python将文本转换成图片输出的方法
Apr 28 #Python
Python psutil模块简单使用实例
Apr 28 #Python
Python RuntimeError: thread.__init__() not called解决方法
Apr 28 #Python
Python标准库defaultdict模块使用示例
Apr 28 #Python
You might like
模仿OSO的论坛(五)
2006/10/09 PHP
一些关于PHP的知识
2006/11/17 PHP
php中截取字符串支持utf-8
2007/01/18 PHP
PHP实现的交通银行网银在线支付接口ECSHOP插件和使用例子
2014/05/10 PHP
php结合正则批量抓取网页中邮箱地址
2015/05/19 PHP
php获取网站百度快照日期的方法
2015/07/29 PHP
yii2实现根据时间搜索的方法
2016/05/25 PHP
深入浅出讲解:php的socket通信原理
2016/12/03 PHP
PHP二维数组去重算法
2016/12/17 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
JavaScript中的Math.E属性使用详解
2015/06/12 Javascript
分享使用AngularJS创建应用的5个框架
2015/12/05 Javascript
AnjularJS中$scope和$rootScope的区别小结
2016/09/18 Javascript
EasyUI的TreeGrid的过滤功能的解决思路
2017/08/08 Javascript
基于vue.js无缝滚动效果
2018/01/25 Javascript
security.js实现的RSA加密功能示例
2018/06/06 Javascript
微信上传视频文件提示(推荐)
2018/11/22 Javascript
如何基于js判断浏览器版本
2020/02/20 Javascript
ant design vue中表格指定格式渲染方式
2020/10/28 Javascript
[51:17]完美世界DOTA2联赛循环赛Inki vs DeMonsTer 第二场 10月30日
2020/10/31 DOTA
python中常用检测字符串相关函数汇总
2015/04/15 Python
Python中getattr函数和hasattr函数作用详解
2016/06/14 Python
python+django+sql学生信息管理后台开发
2018/01/11 Python
浅谈python可视化包Bokeh
2018/02/07 Python
Python生成MD5值的两种方法实例分析
2019/04/26 Python
Python将文字转成语音并读出来的实例详解
2019/07/15 Python
python字符串的index和find的区别详解
2020/06/20 Python
Python 合并拼接字符串的方法
2020/07/28 Python
Python如何使用ConfigParser读取配置文件
2020/11/12 Python
法国二手手袋、手表和奢侈珠宝购物网站:Collector Square
2018/07/05 全球购物
Hello Molly美国:女性时尚在线
2019/08/26 全球购物
联想阿根廷官方网站:Lenovo Argentina
2019/10/14 全球购物
学期自我评价
2014/01/27 职场文书
阳光体育活动实施方案
2014/05/25 职场文书
六查六看心得体会
2014/10/14 职场文书
2014年幼儿园德育工作总结
2014/12/17 职场文书