浅析Python装饰器中的@property

共 3869字,需浏览 8分钟

 ·

2021-04-10 10:07

点击上方“Go语言进阶学习”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

不堪玄鬓影,来对白头吟。

一、使用@property优点

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

案例分析

例:

class Exam(object):    def __init__(self, score):        self._score = score
def get_score(self): return self._score
def set_score(self, val): if val < 0: self._score = 0 elif val > 100: self._score = 100 else: self._score = val
e = Exam(60)print(e.get_score())
e.set_score(70)print(e.get_score())

代码解析:

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

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

例 :

class Exam(object):    def __init__(self, score):        self._score = score
@property def score(self): return self._score
@score.setter def score(self, val): if val < 0: self._score = 0 elif val > 100: self._score = 100 else: self._score = val

e = Exam(60)print(e.score)
e.score = 90print(e.score)
e.score = 200print(e.score)

注:

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

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

class Exam(object):    def __init__(self, score):        self._score = score
@property def score(self): return self._score
e = Exam(60)print(e.score)e.score = 200 # score 是只读属性,不能设置值print(e.score)


二、@property的力量

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

例 :

class Celsius:    def __init__(self, temperature = 0):        self.temperature = temperature
def to_fahrenheit(self): return (self.temperature * 1.8) + 32
def get_temperature(self): print("获得的值") return self._temperature
def set_temperature(self, value): if value < -273: raise ValueError("零下273度是不可能的") print("设定值") self._temperature = value
temperature = property(get_temperature,set_temperature)

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

c = Celsius()print(c.temperature)

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

此分配自动称为set_temperature()。

2. 属性的作用。

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

例:

c.temperature = 37print(c.temperature)print(c.to_fahrenheit())

注:

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


三、深入了解property

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

语法

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

参数解析

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

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

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

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

语法:

temperature = property(get_temperature,set_temperature)

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

# 创建空属性temperature = property()# 设置 fgettemperature = temperature.getter(get_temperature)# 设置 fsettemperature = temperature.setter(set_temperature)

注:

这两段代码是等效的。

不定义名称get_temperature,set_temperature。

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

2. 案例

例:

class Celsius:    def __init__(self, temperature = 0):        self._temperature = temperature
def to_fahrenheit(self): return (self.temperature * 1.8) + 32
@property def temperature(self): print("获得值") return self._temperature
@temperature.setter def temperature(self, value): if value < -273: raise ValueError("零下273度是不可能的") print("零下273度是不可能的") self._temperature = valuec=Celsius()c.temperature = 37print(c.temperature)

注:

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


四、总结

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

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

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

------------------- End -------------------

往期精彩文章推荐:

浏览 39
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报