参考链接: Python @property装饰器

Python中有一个被称为属性函数(property)的小概念,它可以做一些有用的事情。在这篇文章中,我们将看到如何能做以下几点:

将类方法转换为只读属性重新实现一个属性的setter和getter方法

@property

考察 Student 类:

class Student(object):

def __init__(self, name, score):

self.name = name

self.score = score

当我们想要修改一个 Student 的 scroe 属性时,可以这么写:

s = Student('Bob', 59)

s.score = 60

但是也可以这么写:

s.score = 1000

显然,直接给属性赋值无法检查分数的有效性。

如果利用两个方法:

class Student(object):

def __init__(self, name, score):

self.name = name

self.__score = score

def get_score(self):

return self.__score

def set_score(self, score):

if score < 0 or score > 100:

raise ValueError('invalid score')

self.__score = score

这样一来,s.set_score(1000) 就会报错。

这种使用 get/set 方法来封装对一个属性的访问在许多面向对象编程的语言中都很常见。

但是写 s.get_score() 和 s.set_score() 没有直接写 s.score 来得直接。

有没有两全其美的方法?----有。

因为Python支持高阶函数,在函数式编程中我们介绍了装饰器函数,可以用装饰器函数把 get/set 方法“装饰”成属性调用:

class Student(object):

def __init__(self, name, score):

self.name = name

self.__score = score

@property

def score(self):

return self.__score

@score.setter

def score(self, score):

if score < 0 or score > 100:

raise ValueError('invalid score')

self.__score = score

注意: 第一个score(self)是get方法,用@property装饰,第二个score(self, score)是set方法,用@score.setter装饰,@score.setter是前一个@property装饰后的副产品。

现在,就可以像使用属性一样设置score了:

>>> s = Student('Bob', 59)

>>> s.score = 60

>>> print s.score

>>> s.score = 1000

Traceback (most recent call last):

...

ValueError: invalid score

说明对 score 赋值实际调用的是 set方法。

任务

如果没有定义set方法,就不能对“属性”赋值,这时,就可以创建一个只读“属性”。

通过上面的代码可以看出,@property 修饰函数score(getter),将score函数变成score属性输出,此外,@property 本身又创建了另一个装饰器@score.setter,负责把一个 setter 函数变成属性赋值,于是,我们虽然看到了类Student内部定义了两个函数score,对,没错,都是score,但是,他们却被不同的装饰器装饰,getter函数被@property修饰,setter函数被@property创建的函数的setter装饰器@score.setter修饰,因此,我们可以直接用s.score=90来代替s.set_socre(90),达到给score属性赋值的效果,简单粗暴,精益求精,虽然实现的效果一样,但是写起来,还是直接s.score=90来的更舒坦一些。从目的上讲,@property 修饰函数就是为了让调用者能用更少的代码去实现同样的功能。

拓展问题:

请给Student类加一个grade属性,根据 score 计算 A(>=80)、B、C(<60)。

class Student(object):

def __init__(self, name, score):

self.name = name

self.__score = score

self.__grade = None

@property

def score(self):

return self.__score

@score.setter

def score(self, score):

if score < 0 or score > 100:

raise ValueError('invalid score')

self.__score = score

# 请给Student类加一个grade属性,根据score 计算

# A( >= 80)、B、C( < 60)。

@property

def grade(self):

if self.score >= 80:

self.__grade = "A"

elif self.score >= 60:

self.__grade = "B"

else:

self.__grade = "C"

return self.__grade

s = Student('Bob', 59)

# print(s.grade)

s.score = 60

print(s.grade)

#

# s.score = 99

# print(s.grade)

分析:

新添加的grade属性,是只读属性,可以只调用get方法,不调用set方法,来实现上述功能。

总结:

@property装饰器就是负责把一个方法变成属性调用,通常用在属性的get方法和set方法,通过设置@property可以实现实例成员变量的直接访问,又保留了参数的检查。另外通过设置get方法而不定义set方法可以实现成员变量的只读属性。

[转载] python中@property装饰器相关推荐

  1. python装饰器 property_Python中@property装饰器的使用技巧性解析(代码示例)

    Python中@property装饰器的技巧性用法(代码示例) 本篇文章给大家带来的内容是关于Python中@property装饰器的技巧性用法(代码示例),有一定的参考价值,有需要的朋友可以参考一下 ...

  2. [转载]理解PYTHON中的装饰器

    [翻译]理解PYTHON中的装饰器 来源stackoverflow上的问题 链接 python的函数是对象 要理解装饰器,首先,你必须明白,在python中,函数是对象. 这很重要. 简单例子来理解为 ...

  3. pythonproperty装饰器_实例讲解Python编程中@property装饰器的用法

    取值和赋值 class Actress(): def __init__(self): self.name = 'TianXin' self.age = 5 类Actress中有两个成员变量name和a ...

  4. python装饰器 property_介绍Python的@property装饰器的用法

    在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 这显然不合逻辑.为了限制score的 ...

  5. [转载] python 闭包和装饰器详解

    参考链接: Python中的装饰器 python 闭包,装饰器 一 闭包 如果在一个函数的内部定义了另一个函数,外部的函数叫它外函数,内部的函数叫它内函数. 1 闭包条件 1 在一个外函数中定义了一个 ...

  6. 介绍Python的@property装饰器的用法_python_脚本之家

    介绍Python的@property装饰器的用法_python_脚本之家 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Studen ...

  7. python装饰器原理-python 中的装饰器及其原理

    装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...

  8. python类装饰器详解-python 中的装饰器详解

    装饰器 闭包 闭包简单的来说就是一个函数,在该函数内部再定义一个函数,并且这个内部函数用到了外部变量(即是外部函数的参数),最终这个函数返回内部函数的引用,这就是闭包. def decorator(p ...

  9. python中的装饰器decorator

    python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x):return ...

最新文章

  1. Qt学习之路(17): Qt标准对话框之QMessageBox
  2. Android中再按一次退出实现
  3. Spring框架使用规范和IOC的开发
  4. QQ 5.0侧滑HorizontalScrollView以及自定义ViewGroup
  5. android 处理http状态码,OkHttp(Retrofit)对于http状态码202的处理
  6. CSS魔法堂:那个被我们忽略的outline 1
  7. 一步步编写操作系统 22 硬盘操作方法
  8. 学位论文是根,学术论文是叶
  9. 阿里重磅开源首款自研科学计算引擎Mars,揭秘超大规模科学计算
  10. GTN-Graph Transformer Network 图变换网络 NeurIPS2019
  11. SENet(ILSVRC2017-最后一个冠军)
  12. SpringBoot加载静态资源
  13. 第一次的数电作业-----数据选择,代码转换,译码
  14. android 360游戏sdk,360dev 单机游戏接入SDK
  15. excel查看编码格式_Excel表格中格式转换的这些套路,你都get了吗?
  16. 计算机安全的最后一道防线,网络安全的第一道防线是(图文)
  17. 使用python Telegram 机器人推送消息
  18. 浅谈windows 编程中SendMessage函数的妙用!!!
  19. mysql联合union查询_Mysql联合查询UNION和UNION ALL的使用介绍
  20. python股票量化交易(8)---K线图:锤头,射击之星,早晨之星

热门文章

  1. 【CCCC】L3-005 垃圾箱分布 (30分),Dijkstra跑n遍 = 多源最短路,emm
  2. 【HAOI2008】【BZOJ1045】糖果传递(环形纸牌均分,前缀和)
  3. java流程控制结构不包括_以下各项中不属于Java语言流程控制结构的是()。
  4. simpana oracle,华为认证云运维专家(HCIE-CDO)
  5. 睡觉老往下跑是怎么回事_孩子冬季睡觉“不老实,踢被子”,可不单纯是热,娃的苦衷要了解...
  6. python官方文档怎么样_python官方文档
  7. 用模板类实现shared_ptr和unique_ptr
  8. 2017 Multi-University Training Contest - Team 4:1003. Counting Divisors(积性函数)
  9. opencv 显示程序运行时间
  10. [debug] 令人智熄的调试:忘记加return