装饰器:以某种方式增强函数。
两大特性:1、可以将被装饰的函数替换成其他函数。
2、在加载模块时立即执行。
案例1
def make_avarage():
count=0
total=0
def averager(new_value):
count+=1
total+=new_value
return total/count
return averager
这里会报错,averager里面是一个新的 count、total变量
案例2
使用nolocal作用:将变量标记为自由变量,
def make_avarage():
count=0
total=0
def averager(new_value):
nonlocal count,total
count+=1
total+=new_value
return total/count
return averager
案例3
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Sun May 3 23:27:22 2020 @author: root """ promos=[] def promotion(promo_func): promo.append(promo_func) return promo_func @promotion def FidelityPromo(order): return order.total()*0.05 if order.customer.fidelity>=1000 else 0 @promotion def BulkItemPromo(order): discount = 0 for item in order.cart: if item.quantity>=20: discount+=item.total()*0.1 return discount @promotion def LargeOrderPromo(order): discount_items = {item.product for item in order.cart} if len(discount_items)>=10: return order.total()*0.07 return 0 def best_promo(order): return max(promo(order) for promo in promos)
二、@property:方法伪装属性,方法返回值及属性值,被装饰方法不能有参数,必须实例化后调用,类不能调用
#@ property
#将一个方法伪装成属性,被修饰的特性方法,内部可以实现处理逻辑,但对外提供统一的调用方式,实现一个实例属性的
getter
setter
d elete
三种方法的内部逻辑,具体含义看示
class Data: def __init__(self): self.number = 123 @property def operation(self): return self.number
@operation.getter
def operation(self):
return self.number @operation.setter def operation(self, number): self.number = number @operation.deleter def operation(self): del self.number
案例1----普通写法
class Student(object):
def get_score(self):
return self._score
def set_score(self,value):
if not isinstance(value,int):
raise ValueError(‘pppppp‘)
if value < 0 or value > 100:
raise ValueError(‘score must between 0 ~ 100!‘)
self._score = value
Python内置的@property装饰器就是负责把一个方法变成属性调用
案例1----装饰器写法
class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError(‘pppppp‘)
if value < 0 or value > 100:
raise ValueError(‘score must between 0 ~ 100!‘)
self._score = value
s=Student()
s.score=60
s.score=9999
print (s.score)
三、类装饰器:类装饰器使用地方较少,核心是通过复写类的回调方法call.
装饰器应用场景:
1、引入日志
2、函数执行时间统计
3、执行函数前预备处理
执行函数后清理功能
权限校验等场景
缓存
方法:__call__
class Add:
def __init__(self, fn):
print("初始化")
self.num = 44
self.fn = fn
def __call__(self, *args, **kwargs
):
print("类装饰器开始工作")
return self.fn(self.num)
@Add
def test(n):
return 4+n
if __name__ == ‘__main__‘:
num = test()
print(num)
结果:
原文:https://www.cnblogs.com/1314520xh/p/12824712.html