浅析Python装饰器中的@property

一、使用@property优点

将类方法转换为类属性,可以用来直接获取属性值或者对属性进行赋值。

案例分析

例:

1class Exam(object): 2 def __init__(self, score): 3 self._score = score 4 5 def get_score(self): 6 return self._score 7 8 def set_score(self, val): 9 if val < 0: 10 self._score = 0 11 elif val > 100: 12 self._score = 100 13 else: 14 self._score = val 15 16e = Exam(60) 17print(e.get_score()) 18 19e.set_score(70) 20print(e.get_score())

代码解析:

定义了一个 Exam 类,为了避免直接对 _score 属性操作,提供了 get_score 和 set_score 方法,这样起到了封装的作用,把一些不想对外公开的属性隐蔽起来,而只是提供方法给用户操作,在方法里面,可以检查参数的合理性等。

Python 提供了 property 装饰器,被装饰的方法,可以将其『当作』属性来用。

例 :

1class Exam(object): 2 def __init__(self, score): 3 self._score = score 4 5 @property 6 def score(self): 7 return self._score 8 9 @score.setter 10 def score(self, val): 11 if val < 0: 12 self._score = 0 13 elif val > 100: 14 self._score = 100 15 else: 16 self._score = val 17 18 19e = Exam(60) 20print(e.score) 21 22e.score = 90 23print(e.score) 24 25e.score = 200 26print(e.score)

注:

给方法 score 加上了 @property,于是可以把 score 当成一个属性来用,此时,又会创建新的score.setter,它可以把被装饰的方法变成属性来赋值。

另外,也不一定要使用 score.setter 这个装饰器,这时 score 就变成一个只读属性:

1class Exam(object): 2 def __init__(self, score): 3 self._score = score 4 5 @property 6 def score(self): 7 return self._score 8 9e = Exam(60) 10print(e.score) 11e.score = 200 # score 是只读属性,不能设置值 12print(e.score)

二、@property的力量

python处理上述问题的方法是使用property。可以这样来实现它。

例 :

1 2class Celsius: 3 def __init__(self, temperature = 0): 4 self.temperature = temperature 5 6 def to_fahrenheit(self): 7 return (self.temperature * 1.8) + 32 8 9 def get_temperature(self): 10 print("获得的值") 11 return self._temperature 12 13 def set_temperature(self, value): 14 if value < -273: 15 raise ValueError("零下273度是不可能的") 16 print("设定值") 17 self._temperature = value 18 19 temperature = property(get_temperature,set_temperature)

并且,一旦运行,在shell中发出以下代码。

1 2c = Celsius() 3print(c.temperature)

创建对象时,将调用init ()方法。此方法的线为self.temperature = temperature。

此分配自动称为set_temperature()。

2. 属性的作用。

任何访问如c.temperature都会自动调用get_temperature()。

例:

1 2c.temperature = 37 3print(c.temperature) 4print(c.to_fahrenheit())

注:

温度值存储在私有变量_temperature中。temperature属性是一个属性对象,它提供了与此私有变量的接口。

三、深入了解property

在Python中,property()是一个内置函数,用于创建并返回属性对象。

语法

property(fget=None, fset=None, fdel=None, doc=None)

参数解析

fget为获取属性值的函数,fset为设置属性值的函数,fdel为删除属性的函数,doc为字符串(如注释)。从实现中可以看出,这些函数参数是可选的。

可以简单地按照以下方式创建属性对象。

1 2property(fget=None, fset=None, fdel=None, doc=None) 3print(property())

1. 属性对象有三个方法,getter()、setter()和deleter()。

语法:

temperature = property(get_temperature,set_temperature)

用于稍后指定fget、fset和fdel。

1 2# 创建空属性 3temperature = property() 4# 设置 fget 5temperature = temperature.getter(get_temperature) 6# 设置 fset 7temperature = temperature.setter(set_temperature)

注:

这两段代码是等效的。

不定义名称get_temperature,set_temperature。

因为它们是不必要的,并且会影响类命名空间。为此,在定义getter和setter函数时重用了名称temperature。

2. 案例

例:

1class Celsius: 2 def __init__(self, temperature = 0): 3 self._temperature = temperature 4 5 def to_fahrenheit(self): 6 return (self.temperature * 1.8) + 32 7 8 @property 9 def temperature(self): 10 print("获得值") 11 return self._temperature 12 13 @temperature.setter 14 def temperature(self, value): 15 if value < -273: 16 raise ValueError("零下273度是不可能的") 17 print("零下273度是不可能的") 18 self._temperature = value 19c=Celsius() 20c.temperature = 37 21print(c.temperature)

注:

实现是制作属性的简单方法和推荐方法。在Python中寻找属性时,很可能会遇到这些类型的构造。

四、总结

本文基于Python基础,介绍了@property 如何把方法变成了属性。通过案例的分析,代码的展示。介绍了@property的力量,以及提供了相应错误的解决方案处理方法。属性的作用。

欢迎大家积极尝试,有时候看到别人实现起来很简单,但是到自己动手实现的时候,总会有各种各样的问题,切勿眼高手低,勤动手,才可以理解的更加深刻。

代码很简单,希望对你学习有帮助。

-------------------********************************** End **********-------------**-----********-**********************************

往期精彩文章推荐:

欢迎各位大佬点击链接加入群聊【helloworld开发者社区】:https://jq.qq.com/?_wv=1027&k=mBlk6nzX进群交流IT技术热点。

本文转自 https://mp.weixin.qq.com/s/SRZjkqnLbOfbr1tP2X_o-A,如有侵权,请联系删除。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

一篇文章带教会你Python访问限制那些事儿

一、前言在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。二、案例分析以Teacher类的定义来看,外部代码还是可以自由地修改一个实例的name、score属性。classTeacher(object):definit(self,name,score):s

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )