1.装饰器和描述器融合:一个类,既是装饰器也是描述器。是很多高级库和框架的重要工具之一
class Discr: # Discr是装饰器同时也是个描述器 def __init__(self, func): self.func = func # print(func) #func 是传进来的area方法 def __get__(self, instance, owner): return self.func(instance) # instance是对象test1 class Test: def __init__(self, length, width): self.lenth = length self.width = width @Discr # area=Discr(area) area被装饰器代理了,Discr是装饰器同时也是个描述器 def area(self): return self.width * self.lenth test1 = Test(2, 5) print(test1.area) ‘‘‘area方法被Discr(area)代理了,同时,Discr(area)也是实例化,会执行__init__。 它也是描述符,会调用__get__‘‘‘
上面完成了一个自定义的property。实例调用没问题,类调用还会报错,修改后如下
class Discr: # Discr是装饰器同时也是个描述器 def __init__(self, func): self.func = func # print(func) #func 是传进来的area方法 def __get__(self, instance, owner): if instance is None:#类调用,instance为空 return self return self.func(instance) # instance是对象test1 class Test: def __init__(self, length, width): self.lenth = length self.width = width @Discr # area=Discr(area) area被装饰器代理了,Discr是装饰器同时也是个描述器 def area(self): return self.width * self.lenth test1 = Test(2, 5) # print(test1.area) print(Test.area) ‘‘‘area方法被Discr(area)代理了,同时,Discr(area)也是实例化,会执行__init__。 它也是描述符,会调用__get__‘‘‘
2.实现延迟计算,或者说缓存
方法运行有可能代码很长,一次运行后要把结果保存起来,下次直接读取。那么存到哪里呢?字典!
class Discr: # Discr是装饰器同时也是个描述器 def __init__(self, func): self.func = func # print(func) #func 是传进来的area方法 def __get__(self, instance, owner): if instance is None:#类调用,instance为空 return self res=self.func(instance) # instance是对象test1 setattr(instance,self.func.__name__,res) print(‘from __get__‘) return res # def __set__(self, instance, value): # pass class Test: def __init__(self, length, width): self.lenth = length self.width = width @Discr # area=Discr(area) area被装饰器代理了,Discr是装饰器同时也是个描述器 def area(self): return self.width * self.lenth test1 = Test(2, 5) print(test1.area) print(test1.__dict__) print(test1.area) ‘‘‘__dict__有了,下次直接读取,实例属性优先级>非数据属性 若有__set__,在__dic__保存结果不成功‘‘‘
python基础-面向对象(二十四)面向对象进阶(十二)装饰器和描述符融合-自定义property
原文:https://www.cnblogs.com/liaoyifu/p/14152766.html