介绍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显示天气预报
Mar 02 Python
使用python的pandas库读取csv文件保存至mysql数据库
Aug 20 Python
用python实现k近邻算法的示例代码
Sep 06 Python
对python的unittest架构公共参数token提取方法详解
Dec 17 Python
Python3 SSH远程连接服务器的方法示例
Dec 29 Python
pandas读取CSV文件时查看修改各列的数据类型格式
Jul 07 Python
Python实现基于SVM的分类器的方法
Jul 19 Python
Python 用三行代码提取PDF表格数据
Oct 13 Python
Python Django form 组件动态从数据库取choices数据实例
May 19 Python
python 利用opencv实现图像网络传输
Nov 12 Python
python statsmodel的使用
Dec 21 Python
python-图片流传输的思路及示例(url转换二维码)
Dec 21 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生成略缩图代码
2012/07/16 PHP
php文件上传你必须知道的几点
2015/10/20 PHP
根据鼠标的位置动态的控制层的位置
2009/11/24 Javascript
jquery实现网站超链接和图片提示效果
2013/03/21 Javascript
javascipt:filter过滤介绍及使用
2014/09/10 Javascript
8个超实用的jQuery功能代码分享
2015/01/08 Javascript
Node.js实用代码段之获取Buffer对象字节长度
2016/03/17 Javascript
响应式表格之固定表头的简单实现
2016/08/26 Javascript
利用JS判断鼠标移入元素的方向
2016/12/11 Javascript
JavaScript原生编写《飞机大战坦克》游戏完整实例
2017/01/04 Javascript
JavaScript实现移动端轮播效果
2017/06/06 Javascript
微信小程序checkbox组件使用详解
2018/01/31 Javascript
node.js监听文件变化的实现方法
2019/04/17 Javascript
基于JS开发微信网页录音功能的实例代码
2019/04/30 Javascript
通过js示例讲解时间复杂度与空间复杂度
2019/08/06 Javascript
vue点击标签切换选中及互相排斥操作
2020/07/17 Javascript
解决vue项目axios每次请求session不一致的问题
2020/10/24 Javascript
Python 开发Activex组件方法
2009/11/08 Python
django使用图片延时加载引起后台404错误
2017/04/18 Python
Python3利用Dlib19.7实现摄像头人脸识别的方法
2018/05/11 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
Python编写带选项的命令行程序方法
2019/08/13 Python
django连接mysql数据库及建表操作实例详解
2019/12/10 Python
浅谈pycharm导入pandas包遇到的问题及解决
2020/06/01 Python
pycharm中选中一个单词替换所有重复单词的实现方法
2020/11/17 Python
关于老式浏览器兼容HTML5和CSS3的问题
2016/06/01 HTML / CSS
意大利大型购物中心:Oliviero.it
2017/10/19 全球购物
Coltorti Boutique官网:来自意大利的设计师品牌买手店
2018/11/09 全球购物
abstract是什么意思
2012/02/12 面试题
轻金属冶金专业毕业生自荐信
2013/11/02 职场文书
商场父亲节活动方案
2014/08/27 职场文书
政府班子四风问题整改措施
2014/10/04 职场文书
技术股东合作协议书
2014/12/02 职场文书
前台岗位职责
2015/02/13 职场文书
使用python+pygame开发消消乐游戏附完整源码
2021/06/10 Python
HTML中的表格元素介绍
2022/02/28 HTML / CSS