Python装饰器之property()详解
1. 作甚装饰器?
官方界说:装饰器是一个很著名的设计模式,常常被用于有切面需求的场景,较为经典的有插入日志、机能测试、事务处理惩罚等。装饰器是办理这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数成果自己无关的类似代码并继承重用。归纳综合的讲,装饰器的浸染就是为已经存在的工具添加特另外成果。
Python中总共包罗三个内置装饰器:
① staticmethod
② classmethod
③ property
2. 属性函数 property() 浅谈
2.1 为什么要利用 property?
凡是,我们在会见属性和给属性赋值的时候,都是对 类和实例 __dict__ 打交道的;但假如我们想要类型属性会见,有两种方法可用:①数据描写符 ,②. property() 属性函数。
然而,我们知道,描写符相比拟力巨大,对付新手来说,用起来很吃力,那么不妨试试property(),相对付描写符这个大的历程,property就相当于线程。
2.2 函数原型:
property(fget=None, fset=None, fdel=None, doc=None)
2.3 普通要领界说:
假设 calss Normal中有一个私有变量 __x,如下代码所示:
#code 1 class Normal: def __init__(self): self.__x = None def getx(self): return self.__x def setx(self, value): self.__x = value def delx(self): del self.__x tN = Normal() print(tN.__count)
输出功效(报错了)
Traceback (most recent call last): File "C:/Users/Administrator/AppData/Local/Programs/Python/Python35/property.py", line 15, in <module> print(tN.__count) AttributeError: 'Normal' object has no attribute '__count'
为啥报错了呢?因为 实例tN的属性 __x 为私有属性,不能直接会见,为此我们只能挪用内部界说的 要领;
tN = Normal() tN.setx(10) print(tN.getx())
输出功效:
6 10
利用内部的要领,可以容易的获得实例的可能类的私有属性值;
然而,假如我想把 class Normal 的 setx要领名改成了其它(如 Normal_setx),外部许多处所用到了该函数,是不是我需要一个一个的去找该要领的挪用所在,然后一个一个的改呢?
c语言或者会,但Python,一个高级语言,怎么会这么点事都办理不了呢?
那么,该如何办理以上问题呢?
其实有两种要领。
要领一:利用 属性函数property()
class Normal: def __init__(self): self.__x = None def getx(self): print('getx(): self.__x=', self.__x) return self.__x def setx(self, value): self.__x = value print('setx()') def delx(self): print('delx()') del self.__x y = property(getx, setx, delx, "I'm a property") tN=Normal() tN.y=10 tN.y del tN.y #输出功效: setx() getx(): self.__x= 10 delx()
直接把要领当属性来操纵了,很是利便
要领二:利用 @property 装饰器
class Normal: def __init__(self): self.__x = None @property def xx(self): print('getx(): self.__x=', self.__x) return self.__x @xx.setter def xx(self, value): self.__x = value print('setx()') @xx.deleter def xx(self): print('delx()') del self.__x tN=Normal() tN.xx=10 tN.xx del tN.xx #输出功效信息: setx() getx(): self.__x= 10 delx()
跟要领一 输出同样的功效,证明,这两种要领都可行的(留意:第一个必然是 @property(替代getter哦,否则会报错))。