介绍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写的创建文件夹自定义函数mkdir()
Aug 25 Python
Ubuntu 下 vim 搭建python 环境 配置
Jun 12 Python
Python的装饰器使用详解
Jun 26 Python
Python用 KNN 进行验证码识别的实现方法
Feb 06 Python
Python 使用with上下文实现计时功能
Mar 09 Python
基于python框架Scrapy爬取自己的博客内容过程详解
Aug 05 Python
解决python DataFrame 打印结果不换行问题
Apr 09 Python
Django model重写save方法及update踩坑详解
Jul 27 Python
Python 在 VSCode 中使用 IPython Kernel 的方法详解
Sep 05 Python
python解压zip包中文乱码解决方法
Nov 27 Python
让文件路径提取变得更简单的Python Path库
May 27 Python
python字符串的一些常见实用操作
Apr 06 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 字符转义 注意事项
2009/05/27 PHP
php读取图片内容并输出到浏览器的实现代码
2013/08/08 PHP
PHP中上传多个文件的表单设计例子
2014/11/19 PHP
php使用PDO方法详解
2014/12/27 PHP
PHP页面输出搜索后跳转下一页的处理方法
2016/09/30 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
2019/02/13 PHP
利用404错误页面实现UrlRewrite的实现代码
2008/08/20 Javascript
ExtJs GridPanel简单的增删改实现代码
2010/08/26 Javascript
通过pjax实现无刷新翻页(兼容新版jquery)
2014/01/31 Javascript
js实现获取焦点后光标在字符串后
2014/09/17 Javascript
JavaScript时间操作之年月日星期级联操作
2016/01/15 Javascript
Bootstrap开关(switch)控件学习笔记分享
2016/05/30 Javascript
各式各样的导航条效果css3结合jquery代码实现
2016/09/17 Javascript
javascript实现去除HTML标签的方法
2016/12/26 Javascript
原生js仿淘宝网商品放大镜效果
2017/02/28 Javascript
想用好React的你必须要知道的一些事情
2017/07/24 Javascript
解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
2017/09/22 jQuery
Python设计模式之观察者模式实例
2014/04/26 Python
关于python pyqt5安装失败问题的解决方法
2017/08/08 Python
浅析python打包工具distutils、setuptools
2018/04/20 Python
十分钟利用Python制作属于你自己的个性logo
2018/05/07 Python
Python实现的排列组合、破解密码算法示例
2019/04/12 Python
python简单实现矩阵的乘,加,转置和逆运算示例
2019/07/10 Python
python的range和linspace使用详解
2019/11/27 Python
scrapy-redis分布式爬虫的搭建过程(理论篇)
2020/09/29 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
德国家具在线:Fashion For Home
2017/03/11 全球购物
护理毕业生自我鉴定
2014/02/11 职场文书
党员违纪检讨书
2014/02/18 职场文书
三好学生演讲稿范文
2014/04/26 职场文书
群众路线四风自我剖析材料
2014/10/08 职场文书
党员个人整改方案及措施
2014/10/25 职场文书
学生逃课检讨书
2015/02/17 职场文书
Java日常练习题,每天进步一点点(38)
2021/07/26 Java/Android
Python中re模块的元字符使用小结
2022/04/07 Python
python实现学生信息管理系统(面向对象)
2022/06/05 Python