介绍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获得图片base64编码示例
Jan 16 Python
Python的语言类型(详解)
Jun 24 Python
Python实现PS图像明亮度调整效果示例
Jan 23 Python
python 列表转为字典的两个小方法(小结)
Jun 28 Python
简单了解Python matplotlib线的属性
Jun 29 Python
在自动化中用python实现键盘操作的方法详解
Jul 19 Python
解决Pycharm 导入其他文件夹源码的2种方法
Feb 12 Python
Django 实现将图片转为Base64,然后使用json传输
Mar 27 Python
django 实现手动存储文件到model的FileField
Mar 30 Python
基于python实现对文件进行切分行
Apr 26 Python
怎么快速自学python
Jun 22 Python
python基础之while循环语句的使用
Apr 20 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
php导入excel文件到mysql数据库的方法
2015/01/14 PHP
php强制更新图片缓存的方法
2015/02/11 PHP
php中define用法实例
2015/07/30 PHP
分享PHP守护进程类
2015/12/30 PHP
Javascript的IE和Firefox兼容性汇编
2006/07/01 Javascript
常用的jquery模板插件——jQuery Boilerplate介绍
2014/09/23 Javascript
JavaScript获得url所有参数键值表的方法
2015/03/21 Javascript
使用Jasmine和Karma对AngularJS页面程序进行测试
2016/03/05 Javascript
基于javascript实现tab选项卡切换特效调试笔记
2016/03/30 Javascript
JS实用技巧小结(屏蔽错误、div滚动条设置、背景图片位置等)
2016/06/16 Javascript
初识简单却不失优雅的Vue.js
2016/09/12 Javascript
JavaScript浏览器对象模型BOM(BrowserObjectModel)实例详解
2016/11/29 Javascript
underscore之function_动力节点Java学院整理
2017/07/11 Javascript
使用重写url机制实现验证码换一张功能
2017/08/01 Javascript
Vue中的情侣属性$dispatch和$broadcast详解
2019/03/07 Javascript
原生JS 实现的input输入时表格过滤操作示例
2019/08/03 Javascript
layer ui插件显示tips时,修改字体颜色的实现方法
2019/09/11 Javascript
详解Angular cli配置过程记录
2019/11/07 Javascript
Python中处理字符串之islower()方法的使用简介
2015/05/19 Python
Python素数检测实例分析
2015/06/15 Python
Python中的列表生成式与生成器学习教程
2016/03/13 Python
Python 调用有道翻译接口实现翻译
2020/03/02 Python
python实现电子词典
2020/03/03 Python
Python标准库shutil模块使用方法解析
2020/03/10 Python
Python通过两个dataframe用for循环求笛卡尔积
2020/04/29 Python
Python QT组件库qtwidgets的使用
2020/11/02 Python
Weekendesk意大利:探索多种引人入胜的周末主题
2016/10/14 全球购物
英国当代时尚和街头服饰店:18montrose
2018/12/15 全球购物
StubHub希腊:购买体育赛事、音乐会和剧院门票
2019/08/03 全球购物
台湾三立电视电商平台:电电购
2019/09/09 全球购物
团员个人的自我评价
2013/12/02 职场文书
入党积极分子思想汇报
2014/01/02 职场文书
求职简历的自我评价
2014/01/31 职场文书
党校个人自我鉴定范文
2014/03/28 职场文书
银行金融服务方案
2014/06/11 职场文书
小学生勤俭节约演讲稿
2014/08/28 职场文书