在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改:

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里的property修饰器的更多相关文章

  1. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  2. Python中的@property装饰器

    要了解@property的用途,首先要了解如何创建一个属性. 一般而言,属性都通过__init__方法创建,比如: class Student(object): def __init__(self,n ...

  3. [转载]Python使用@property装饰器--getter和setter方法变成属性

    原贴:为什么Python不需要getter和setter getter 和 setter在java中被广泛使用.一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和sette ...

  4. python设计模式之修饰器模式

    python设计模式之修饰器模式 无论何时我们想对一个对象添加额外的功能,都有下面这些不同的可选方法. [ ] 如果合理,可以直接将功能添加到对象所属的类(例如,添加一个新的方法) [ ] 使用组合 ...

  5. Python使用property函数和使用@property装饰器定义属性访问方法的异同点分析

    Python使用property函数和使用@property装饰器都能定义属性的get.set及delete的访问方法,他们的相同点主要如下三点: 1.定义这些方法后,代码中对相关属性的访问实际上都会 ...

  6. 第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析

    一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...

  7. 对python里的装饰器

    内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人们发明了长裤,有了长裤后宝宝再也不冷了,装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效. 再回到我们的主 ...

  8. Python修饰器的函数式编程

    Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然好像,他们要干的事都 ...

  9. Python修饰器

    Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然好像,他们要干的事都 ...

随机推荐

  1. phpstudy后门漏洞复现php5.2

    前段时间phpstudy被人发现某些版本存在后门,许多人就这样被当作肉鸡长达两年之久 后门隐藏在程序自带的php的php_xmlrpc.dll模块 影响的版本:phpstudy2016和2018 在H ...

  2. Django null=True和blank=True的区别

    今天遇到一个问题: 在restframework框架中开发,数据库了创建了一个model的属性如下所示: remarks = models.CharField(verbose_name=u" ...

  3. maven杂碎汇总

        本来是想写一篇关于maven知识点的详细总结的,但需要看一本书或教材,然后再汇总一下,这样做自然是好的,这个在年前争取做完.本文是主要记录在工作和学习遇到关于maven的一些困惑.很乐意看到它 ...

  4. UVA 12511/CSU 1120 virus 最长公共上升子序列

    第一次接触一个这最长公共上升子序列 不过其实搞清楚了跟最长公共子序列和 最长上升子序列如出一辙 两重循环,对于当前不相等的,等于前一个的值,相等的,等于比当前A[i]小的最大值+1.弄个临时变量记录最 ...

  5. 5 —— node —— 响应一段中文给客户端

    const http = require('http'); const server = http.createServer(); server.on('request',function(req,r ...

  6. bzoj 2451 Uyuw's Concert

    裸的半平面交.感觉这些东西,纯属在考代码能力啊.. #include<cstdio> #include<algorithm> #include<cmath> #de ...

  7. namenode节点无法自动切换主从

    当停掉主namenode节点,从节点无法切换到active状态,有两种可能导致这种问题 1.查看namenode上的zkfc日志,发现没有fuser命令,需要手动安装 yum install -y p ...

  8. scala安装教程及简单配置

    本文将介绍以下内容:Windows下安装scala运行环境,安装编译工具并简单配置,实现著名的“Hello,World". 一,Windows下安装scala运行环境 1.配置jdk,因为s ...

  9. oracle基础知识小结

    一.查看oracle用户.角色信息1.查看所有用户 select * from all_users; select * from user_users; 2.查看用户或角色系统权限 select * ...

  10. 119-PHP调用private成员的方法

    <?php class ren{ //定义人类 private $birthday='1990-12-20'; //定义private修饰的成员属性 public function say_bi ...