介绍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 相关文章推荐
Golang与python线程详解及简单实例
Apr 27 Python
有关Python的22个编程技巧
Aug 29 Python
python用opencv批量截取图像指定区域的方法
Jan 24 Python
python 利用jinja2模板生成html代码实例
Oct 10 Python
pytorch实现mnist分类的示例讲解
Jan 10 Python
pytorch常见的Tensor类型详解
Jan 15 Python
Python读取表格类型文件代码实例
Feb 17 Python
python实现交并比IOU教程
Apr 16 Python
Python+pyftpdlib实现局域网文件互传
Aug 24 Python
python实现自动打卡的示例代码
Oct 10 Python
python在linux环境下安装skimage的示例代码
Oct 14 Python
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
May 31 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
CodeIgniter错误mysql_connect(): No such file or directory解决方法
2014/09/06 PHP
微信公众平台网页授权获取用户基本信息中授权回调域名设置的变动
2014/10/21 PHP
php用户密码加密算法分析【Discuz加密算法】
2016/10/12 PHP
smarty模板数学运算示例
2016/12/11 PHP
使用YII2框架实现微信公众号中表单提交功能
2017/09/04 PHP
IE与FireFox的兼容性问题分析
2007/04/22 Javascript
Javascript操作select方法大全[新增、修改、删除、选中、清空、判断存在等]
2008/09/26 Javascript
浅谈JavaScript中小数和大整数的精度丢失
2016/05/31 Javascript
bootstrap与Jquery UI 按钮样式冲突的解决办法
2016/09/23 Javascript
JavaScript使用享元模式实现文件上传优化操作示例
2018/08/07 Javascript
js作用域和作用域链及预解析
2019/04/11 Javascript
layui之数据表格--与后台交互获取数据的方法
2019/09/29 Javascript
JS实现4位随机验证码
2020/10/19 Javascript
nuxt.js 在middleware(中间件)中实现路由鉴权操作
2020/11/06 Javascript
python ip正则式
2009/05/07 Python
小结Python用fork来创建子进程注意事项
2014/07/03 Python
Python随机数random模块使用指南
2016/09/09 Python
解决python2.7 查询mysql时出现中文乱码
2016/10/09 Python
python运行其他程序的实现方法
2017/07/14 Python
Python hashlib模块用法实例分析
2018/06/12 Python
tensorflow -gpu安装方法(不用自己装cuda,cdnn)
2020/01/20 Python
Python控制台输出时刷新当前行内容而不是输出新行的实现
2020/02/21 Python
Pytorch 使用不同版本的cuda的方法步骤
2020/04/02 Python
Python实现清理微信僵尸粉功能示例【基于itchat模块】
2020/05/29 Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
2020/11/27 Python
python 基于opencv去除图片阴影
2021/01/26 Python
CSS3 transition 实现通知消息轮播条
2020/10/14 HTML / CSS
Swisse官方海外旗舰店:澳大利亚销量领先,自然健康品牌
2017/12/15 全球购物
DJI大疆德国官方商城:大疆无人机
2018/09/01 全球购物
Hush Puppies澳大利亚官网:舒适的男女休闲和正装鞋
2019/08/24 全球购物
SCHIESSER荷兰官方网站:德国内衣专家
2020/10/09 全球购物
实习指导老师评语
2014/04/26 职场文书
廉政教育的心得体会
2014/09/01 职场文书
2014年班长个人工作总结
2014/11/14 职场文书
2015年数学教研组工作总结
2015/05/23 职场文书
vue完美实现el-table列宽自适应
2021/05/08 Vue.js