浅析Python装饰器中的@property

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

[[392255]]

一、使用@property优点

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

案例分析

例:

  1. class 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.  
  16. e = Exam(60) 
  17. print(e.get_score()) 
  18.  
  19. e.set_score(70) 
  20. print(e.get_score()) 

代码解析:

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

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

例 :

  1. class 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.  
  19. e = Exam(60) 
  20. print(e.score) 
  21.  
  22. e.score = 90 
  23. print(e.score) 
  24.  
  25. e.score = 200 
  26. print(e.score) 

注:

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

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

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

二、@property的力量

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

例 :

  1. class 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.     def get_temperature(self): 
  9.         print("获得的值"
  10.         return self._temperature 
  11.  
  12.     def set_temperature(self, value): 
  13.         if value < -273: 
  14.             raise ValueError("零下273度是不可能的"
  15.         print("设定值"
  16.         self._temperature = value 
  17.  
  18.     temperature = property(get_temperature,set_temperature) 

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

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

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

此分配自动称为set_temperature()。

2. 属性的作用。

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

例:

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

注:

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

三、深入了解property

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

语法

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

参数解析

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

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

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

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

语法:

  1. temperature = property(get_temperature,set_temperature) 

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

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

注:

这两段代码是等效的。

不定义名称get_temperature,set_temperature。

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

2. 案例

例:

  1. class 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 
  19. c=Celsius() 
  20. c.temperature = 37 
  21. print(c.temperature) 

注:

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

四、总结

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

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

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

 

责任编辑:姜华 来源: Go语言进阶学习
相关推荐

2021-02-01 14:17:53

装饰器外层函数里层函数

2020-11-17 09:10:44

装饰器

2021-04-15 15:20:46

PythonProperty装饰器

2016-11-01 09:24:38

Python装饰器

2023-02-07 07:47:52

Python装饰器函数

2010-02-01 17:50:32

Python装饰器

2011-07-19 17:18:35

Objective-C Property

2022-09-19 23:04:08

Python装饰器语言

2022-09-27 11:01:08

Python装饰器

2023-12-11 15:51:00

Python装饰器代码

2021-07-27 15:58:12

Python日志代码

2021-06-01 07:19:58

Python函数装饰器

2010-02-01 14:28:37

Python全局变量

2022-09-21 09:04:07

Python装饰器

2023-12-13 13:28:16

装饰器模式Python设计模式

2020-10-16 16:28:54

Python开发技术

2021-10-30 18:59:15

Python

2022-10-21 07:50:35

装饰器Python编程

2019-11-25 14:05:47

Python装饰器数据

2020-05-10 16:59:56

Python装饰器开发
点赞
收藏

51CTO技术栈公众号