介绍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 相关文章推荐
python3模拟百度登录并实现百度贴吧签到示例分享(百度贴吧自动签到)
Feb 24 Python
python通过装饰器检查函数参数数据类型的方法
Mar 13 Python
说一说Python logging
Apr 15 Python
python 自动化将markdown文件转成html文件的方法
Sep 23 Python
windows 下python+numpy安装实用教程
Dec 23 Python
Python爬虫实例_城市公交网络站点数据的爬取方法
Jan 10 Python
tensorflow 获取模型所有参数总和数量的方法
Jun 14 Python
实例讲解Python中整数的最大值输出
Mar 17 Python
python生成器推导式用法简单示例
Oct 08 Python
Python selenium页面加载慢超时的解决方案
Mar 18 Python
Python使用Paramiko控制liunx第三方库
May 20 Python
Python中with上下文管理协议的作用及用法
Mar 18 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编码规范-php coding standard
2007/03/16 PHP
5种PHP创建数组的实例代码分享
2014/01/17 PHP
destoon设置自定义搜索的方法
2014/06/21 PHP
PHP正则+Snoopy抓取框架实现的抓取淘宝店信誉功能实例
2017/05/17 PHP
jQuery帮助之CSS尺寸(五)outerHeight、outerWidth
2009/11/14 Javascript
Javascript之旅 对象的原型链之由来
2010/08/25 Javascript
jquery 年会抽奖程序
2011/12/22 Javascript
javascript五图轮播切换实用版
2012/08/17 Javascript
将input file的选择的文件清空的两种解决方案
2013/10/21 Javascript
dreamweaver 8实现Jquery自动提示
2014/12/04 Javascript
jQuery实现强制cookie过期方法汇总
2015/05/22 Javascript
详解AngularJS跨页面传值(ui-router)
2017/08/23 Javascript
Thinkphp5微信小程序获取用户信息接口的实例详解
2017/09/26 Javascript
[48:27]EG vs Liquid 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
Python程序中用csv模块来操作csv文件的基本使用教程
2016/03/03 Python
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
2016/07/04 Python
一个基于flask的web应用诞生(1)
2017/04/11 Python
Python3 replace()函数使用方法
2018/03/19 Python
不管你的Python报什么错,用这个模块就能正常运行
2018/09/14 Python
Python编程中flask的简介与简单使用
2018/12/28 Python
python查询文件夹下excel的sheet名代码实例
2019/04/02 Python
详解Python3除法之真除法、截断除法和下取整对比
2019/05/23 Python
FFrpc python客户端lib使用解析
2019/08/24 Python
Python SQLAlchemy入门教程(基本用法)
2019/11/11 Python
keras在构建LSTM模型时对变长序列的处理操作
2020/06/29 Python
Python修改DBF文件指定列
2020/12/19 Python
EGO Shoes美国/加拿大:英国时髦鞋类品牌
2018/08/04 全球购物
德国圣伯纳德草药屋:Kräuterhaus Sanct Bernhard(有中文站)
2018/08/05 全球购物
Myprotein丹麦官网:欧洲第一运动营养品牌
2019/04/15 全球购物
Huda Beauty官方商店:化妆和美容产品
2020/09/05 全球购物
社区工作者演讲稿
2014/05/23 职场文书
2015年六一儿童节活动方案
2015/05/05 职场文书
小学推普周活动总结
2015/05/07 职场文书
2016入党心得体会范文
2016/01/06 职场文书
60条职场经典语录,总有一条能触动你的心
2019/08/21 职场文书
Java面试题冲刺第十七天--基础篇3
2021/08/07 面试题